ドキュメントメニュー

クエリ API#

読み取り専用 SQL クエリを送信し、ID でポーリングして、結果を取得します。デフォルトでは署名付き Parquet ダウンロード URL として取得でき、必要に応じてインラインの JSON 行として取得できます。このページのすべての操作は curl で実行できます。

すべてのリクエストは、ベアラー認証情報で認証します。個人アクセストークン(pat_…)はダッシュボードで作成でき、作成時に一度だけ表示されます。

bash
Authorization: Bearer pat_...

トークンはデータへのアクセスを許可するため、サーバー側で保持してください。組織が所有するサービスキー(nsk_…)も同じように動作します。認証を参照してください。

ライフサイクル#

クエリは非同期で実行されます。SQL を送信すると、status: "running"id を含む query オブジェクトがすぐに返されます。statussucceeded または failed になるまで、1~2 秒ごとにポーリングしてください。長時間のクエリでは間隔を延ばしてください。ポーリングもレート制限の対象です。

クエリを送信#

POST/queries

実行中のクエリとともに 202 を返します。Location ヘッダーは、そのクエリの URL を指します。

本文のフィールド
sqlstring必須。読み取り専用の文を 1 つ指定します。制限は後述します。
bash
curl https://api.supernova.ai/queries \
  -H "Authorization: Bearer pat_..." \
  -H "Content-Type: application/json" \
  -d '{"sql": "select currency, count(*) as n from stripe.customers group by currency"}'
json
{
  "object": "query",
  "id": "qr_...",
  "status": "running",
  "created": 1751731200,
  "sql": "select currency, count(*) as n ...",
  "livemode": true
}

Idempotency-Key ヘッダーを使うと、安全に再試行できます。同じキーを再送した場合は再実行せず、元のクエリオブジェクトを返し、Idempotent-Replayed: true ヘッダーでそのことを示します。キーは、最初に実行した sql と完全一致で紐づきます。異なる SQL での再利用は 409 idempotency_key_reused で拒否されるため、内容を変更した再試行で、古いクエリ結果が黙って返されることはありません。キーは 24 時間後に期限切れになります。

ステータスと結果を取得#

GET/queries/{id}

クエリのステータスと、成功後にはその結果を取得します。

クエリパラメーター
formatstringfiles(デフォルト)は署名付き Parquet ダウンロード URL を返し、inline はレスポンス内に行を返します。
limitintegerinline のみ。1 ページあたりの行数。デフォルトは 100、最大は 1000。
starting_afterstringinline のみ。前のページから取得した next_cursor
bash
curl https://api.supernova.ai/queries/qr_... \
  -H "Authorization: Bearer pat_..."
json
{
  "object": "query",
  "id": "qr_...",
  "status": "succeeded",
  "created": 1751731200,
  "duration_ms": 812,
  "row_count": null,
  "files": [
    { "url": "https://storage.googleapis.com/...", "bytes": 18734, "expires": 1751734800 }
  ]
}

duration_ms は実行時間で、実行開始までの時間を含みません。format=inline を指定すると、レスポンス内にページ分割された行が返されます。row_count は全ページの合計です。

json
{
  "object": "query",
  "id": "qr_...",
  "status": "succeeded",
  "created": 1751731200,
  "duration_ms": 812,
  "columns": ["currency", "n"],
  "row_count": 3,
  "data": [
    { "currency": "usd", "n": 1230 },
    { "currency": "eur", "n": 88 },
    { "currency": "gbp", "n": 41 }
  ],
  "has_more": false,
  "next_cursor": null
}

失敗したクエリには、結果の代わりに構造化エラーが含まれます。

json
{
  "object": "query",
  "id": "qr_...",
  "status": "failed",
  "created": 1751731200,
  "duration_ms": 64,
  "error": { "message": "Binder Error: Table \"custmers\" does not exist" }
}

結果ファイル#

署名付き URL に認証は不要です。URL を持つ人は、有効期限までファイルをダウンロードできるため、データそのものと同様に扱ってください。URL の有効期間は 1 時間で、ポーリングのたびに新たに発行されます。現在の結果は単一ファイルですが、将来は大きな結果が分割される可能性があるため、files はリストとして読み取ってください。URL は HTTP Range リクエストに対応しており、Parquet リーダーは必要な範囲を選択して取得できます。

sql
-- DuckDB, in your own environment
select * from read_parquet('https://storage.googleapis.com/...')
text
# pandas
df = pd.read_parquet("https://storage.googleapis.com/...")

ファイルのみのレスポンスでは Parquet を走査しないため、row_countnull になります。正確な件数は、Parquet のメタデータ、または任意のインラインページに含まれます。

結果は速やかに取得してください。クエリとその結果は、送信後少なくとも 24 時間保持されます。

SQL の制限#

次の場合、クエリは実行前に拒否されます(HTTP 400)。文が複数ある場合(multiple_statements)、読み取り専用でない場合(write_not_allowed)、read_parquetread_csv などのファイルまたはストレージ関数を、文字列リテラル内も含めて呼び出す場合(forbidden_function)、100,000 文字を超える場合(sql_too_long)です。書き込み、DDL、セッションのキーワードは拒否されますが、文字列リテラル内では許可されるため、where type = 'DELETE' は使用できます。ストレージ URI(gs://s3://file://)は、クエリ本文のどこにあっても拒否されます。それらを含む列を絞り込むには、スキームを除いた部分文字列で照合してください: where path like '%bucket/x%'

テーブル権限#

組織は、各ユーザー、ロール、認証情報が読み取れるテーブルを決定できます。設定済みの組織では、この認証情報で読み取れないテーブルを指定したクエリは、実行前に 403 とテーブル名を返して拒否されます。同じテーブルはカタログにも表示されません。

json
{
  "error": {
    "type": "permission_error",
    "code": "grant_table_denied",
    "message": "Table stripe.charges is not available to the API for your organization",
    "doc_url": "https://api.supernova.ai/docs#grant_table_denied",
    "request_id": "req_..."
  }
}

エラー#

エラーは、対応する HTTP ステータスと JSON 本文を返します。すべてのレスポンスに Request-Id ヘッダーが含まれるため、サポートへのお問い合わせ時にお知らせください。特定の入力に関するエラーは、その入力を param に示し、doc_url にコードの説明へのリンクを示します。

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "write_not_allowed",
    "message": "Only read-only queries are allowed. ...",
    "doc_url": "https://api.supernova.ai/docs#write_not_allowed",
    "request_id": "req_..."
  }
}

このリソースが返すコード:

ステータスコード意味
400parameter_missing必須パラメーター(例: sql)がない
400write_not_allowedクエリに書き込み、DDL、またはセッションのキーワードが含まれている
400multiple_statements; で区切られた文が複数ある
400forbidden_functionファイルまたはストレージ関数が参照されている
400sql_too_longsql が 100,000 文字を超えている
400invalid_formatformatfiles でも inline でもない
400invalid_cursorstarting_after が前のページのカーソルではない
403grant_table_deniedこの認証情報で読み取れないテーブルがクエリに指定されている
403service_key_permissions_offテーブル権限を有効にしていない組織で、有効なサービスキーが使用された
403grant_introspection_denied制限付きの認証情報では許可されないテーブル一覧の取得を、クエリが行った
404query_not_foundこのアカウントに、その ID のクエリが存在しない
409idempotency_key_reusedIdempotency-Key が、異なる sql ですでに使用されている
429rate_limitedリクエストのレート制限を超過。Retry-After に従ってください
429too_many_queriesアカウントの処理中クエリが多すぎる

レート制限#

各呼び出し元は 1 分間に最大 120 件、各アカウントは呼び出し元全体で 1 分間に最大 600 件のリクエストを送信できます。いずれかを超えると、リクエストは 429 と、秒単位の Retry-After ヘッダーを返します。アカウントごとの同時処理中クエリ数にも上限があります(too_many_queries)。推奨の 1~2 秒間隔であれば、1 つの呼び出し元で数件のクエリを同時にポーリングできます。多数を並行実行する場合は、間隔を延ばしてください。