Pika API 的文档是一个索引加两份文件:机器可读的 llms.txt,以及 dev.pika.art/llms/... 下每个操作各自的规范文档,另外还有一份 OpenAPI 3.1 描述文件放在 dev.pika.art/openapi.json。
Pika API 官方文档在哪里
llms.txt 开头那句同时写给人和智能体:Do not infer endpoint paths, request fields, enum values, pricing, or model support from a model name or from prior knowledge. 接着它排定了取信顺序。
- 目录记录
GET /catalog/apis/{api_id}?expand=inputs,用来查current availability, request fields, required inputs, enum values, and pricing metadata。 - 该操作的
llms/...规范文档,用来看the exact submit endpoint, request and response examples, polling behavior, uploads, and errors。 llms.txt自己只for discovery and routing, not as a substitute for the selected operation's specification。
三份文件不是互为备份,而是各管一段。目录记录里的 input_schema 是机器可校验的那份,报价与枚举值都以它为准;规范文档补的是人读的部分,包括提交响应长什么样、轮询等什么、上传怎么走、报错怎么分。两者混着用最常见的坑,是照着规范文档里的散文示例写字段名,而目录里那个字段已经换了名。
有一条裁决规则高于其余:If a prose example conflicts with the catalog input_schema, follow the catalog schema. 路径写法也由目录定死——Send the slashes in api_id literally。
三跳:提交、轮询、取回

媒体类操作都是异步的,官方把流程写成三次调用:Submit: POST https://api.dev.pika.art/v1/media/{vendor}/{model}/{function},然后 Poll: GET https://api.dev.pika.art/v1/media/jobs/{request_id} until status is completed or failed,完成的任务 carries its download URL in output。
# 第 1 跳——提交。body 属于具体操作,先读它的规范文档。
curl -s -X POST "https://api.dev.pika.art/v1/media/pika/pika-2.5/image-to-video" \
-H "X-API-Key: ${PIKA_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"resolution": "1080p", "duration_s": 5, "image": "https://example.com/frame.png"}'
# 第 2 跳——拿响应里的 id 轮询,直到状态进入终态。
curl -s "https://api.dev.pika.art/v1/media/jobs/${JOB_ID}" \
-H "X-API-Key: ${PIKA_API_KEY}"
# 第 3 跳——读取最终地址。任务完成前这个接口返回 409。
curl -s "https://api.dev.pika.art/v1/media/jobs/${JOB_ID}/content" \
-H "X-API-Key: ${PIKA_API_KEY}"
提交响应不是结果:The submit response returns a job object containing id and status. 要留住这个 id,后面每一次调用等的都是它。Pika API 参考用 Pikaframes 的路径走了一遍同样的三跳。
中间那次轮询是绕不开的成本,官方也给了替代方案。除了任务 id,没有别的状态需要留。重试逻辑可以写得很薄:同一个 body 配固定的幂等键重发,接口会把已有任务原样返回,失败状态也一样。想省掉轮询循环,就在提交时给出回调地址,让终端事件自己推过来。
接口路径,逐字抄自文档
所有调用共用同一个基础地址 https://api.dev.pika.art。
路径是三段结构,和模型名不是一回事。同一个模型可能出现在多个操作里,模型 ID 里的斜杠是字面量,不能当版本号拆开重排。目录里目前登记了 155 个可调用操作,横跨多家供应商,选操作要看函数那一段,而不是看厂牌。
媒体类接口
| 方法与路径 | 作用 |
|---|---|
POST /v1/media/{vendor}/{model}/{function} | 提交一个生成任务。 |
GET /v1/media/jobs/{request_id} | 轮询该任务。 |
GET /v1/media/jobs/{request_id}/content | 以 { "url": ... } 返回结果地址。 |
DELETE /v1/media/jobs/{request_id} | 抹掉已存媒体与提示词,返回 204。 |
支撑类接口
| 方法与路径 | 作用 |
|---|---|
GET /catalog/apis | 列出可调用操作,无需密钥。 |
POST /catalog/apis/{api_id}/quote | 给一份 body 定价,不执行它。 |
GET /billing/balance | 以 micro-USD 读取预付余额。 |
API Key 放在请求头里,还有一个 Google 用户会试错的头
官方把鉴权压成了一行:Authentication header: X-API-Key: $PIKA_API_KEY or Authorization: Bearer $PIKA_API_KEY. Google's x-goog-api-key is not accepted. 吃亏的往往是最后那句。
密钥在 dev.pika.art/keys 创建,PIKA_API_KEY 是官方推荐的环境变量名。用法规则没有留余地:Never place an API key in browser code, a URL, source control, generated output, screenshots, or chat. 浏览器应用 must call Pika through its own authenticated server route。
有两个调用根本不需要密钥,正好用来确认网络连通。
# 公开目录不需要 API key。
curl -s "https://api.dev.pika.art/catalog/apis" | jq .
# OpenAPI 3.1 文件写明了接受的鉴权方式和所有可调用路径。
curl -s https://dev.pika.art/openapi.json | jq '.components.securitySchemes'
如何轮询一个媒体任务
status 有四个取值——queued、running、completed、failed——只有后两个是终态。被拒的提交同样会返回任务对象,status 是 failed 且带上了 error,所以一次终态判断同时覆盖成功和被拒两种情况。
import os
import time
import requests
BASE = "https://api.dev.pika.art"
HEADERS = {"X-API-Key": os.environ["PIKA_API_KEY"]}
TERMINAL = {"completed", "failed"}
def wait_for(job_id, timeout_s=900, interval_s=5):
deadline = time.monotonic() + timeout_s
while True:
job = requests.get(f"{BASE}/v1/media/jobs/{job_id}", headers=HEADERS, timeout=30).json()
if job["status"] in TERMINAL:
return job
if time.monotonic() > deadline:
raise TimeoutError(f"{job_id} still {job['status']} after {timeout_s}s")
time.sleep(interval_s)
job = wait_for(os.environ["JOB_ID"])
if job["status"] == "failed":
# error.code 才是稳定的分支依据;error.message 会变。
raise SystemExit(job["error"]["code"])
print(job["output"]["video"]["url"])
跑完的任务长这样:
{
"id": "media_8f3a2c91-5b7d-4e0a-9c26-31d4f2a8e6b0",
"status": "completed",
"output": {
"media_type": "video",
"video": { "url": "https://api.dev.pika.art/v1/files/video_8f3a2c91.mp4" }
}
}
有两个细节在生产里会咬人:结果接口 answers 409 before the job completes,提前去取是错误而不是捷径;error.code 是 the stable machine-readable value to branch on,而 error.message 只是会变的诊断文本。轮询间隔和总超时都得自己定。官方没有公布单个任务通常跑多久,也没给建议间隔,只有超限时才以 429 的形式返回,而且返回的是带着任务对象的失败信封。稳妥做法是给一个总超时、逐次退避,并把 Retry-After 读进来,而不是把间隔写死。
轮询不合适时可以用 webhook 顶替:在提交 body 顶层传 "webhook_url"(No registration, and a rejected URL answers 400),或者在 Webhooks 页面注册一个端点。投递按 Standard Webhooks 签名,over about 55 hours 内重试,并按 webhook-id 去重;签名密钥要 by an owner or admin, never with an API key 才能读到。
不计费的接口,以及文档里的空白
目录、报价和账单读取都不计费,而 There is no free generation tier and no separate test environment。报价给出的是金额,不是承诺:余额不足、额度用完、参数组合无法定价,都不会在报价阶段暴露。把报价当预算上限,把结算金额当事实记账,中间那道差额靠日消费接口补齐,而Pika API 分层计费说明讲的是这层账怎么构成。
有三处文档一个字都没写:429 背后的速率与并发上限、完成任务的保留时长、结果地址的有效期。官方也没有发布任何厂商专用 SDK,只说 No provider-specific SDK is required。重试安全倒是写清楚了:同一个 body 配一个固定的 Idempotency-Key,Never reuse an idempotency key with a different body;失败任务会在原密钥上重放,所以重试要换新密钥。时长和分辨率是按模型封顶的,所以时长与分辨率对照表要和网页端积分模型放在一起看。
常见问题
该信哪份文档? 先看目录记录,再看操作的 llms/... 规范文档,llms.txt 只用来路由。
基础地址和鉴权头是什么? https://api.dev.pika.art,请求头用 X-API-Key: $PIKA_API_KEY 或 Authorization: Bearer $PIKA_API_KEY。Google's x-goog-api-key is not accepted.
媒体任务怎么轮询? 拿提交响应里的 id 反复调用 GET /v1/media/jobs/{request_id},直到 status 变成 completed 或 failed,再从 output 里读地址。
必须轮询吗? 不必。提交 body 顶层带一个 "webhook_url",同一个任务对象会签名投递到你的服务器,并重试约 55 小时。
先读目录记录,把密钥放进 X-API-Key,再把提交响应当成 id 而不是结果。