API REFERENCE · V1

Pixora API

以编程方式调用 Pixora,把 AI 图像生成嵌入你的应用、自动化工作流或后台批处理。 支持 gpt-image-2 + FLUX,Bearer 鉴权,异步轮询。

1. 快速开始

  1. 登录后访问 /settings, 滚动到 "API Keys" 卡片,点 "创建新 key"。妥善保管返回的明文 key,关闭后无法再次查看。
  2. POST 到 /api/v1/images/generations 提交生成请求:
    bash
    curl https://42ka.cn/api/v1/images/generations \
      -H "Authorization: Bearer pxr_live_..." \
      -H "Content-Type: application/json" \
      -d '{
        "prompt": "A cozy ramen shop on a rainy night, cinematic lighting",
        "model": "gpt-image-2",
        "aspect_ratio": "16:9",
        "num_images": 1
      }'
    返回 202 + 任务 id:
    json
    HTTP/1.1 202 Accepted
    Content-Type: application/json
    
    {
      "id": "abc123def456",
      "status": "pending",
      "poll_url": "/api/v1/images/generations/abc123def456",
      "credits_charged": 100
    }
  3. 轮询任务状态(建议每 5-10 秒),直到 statussuccess /failed /cancelled:
    bash
    curl https://42ka.cn/api/v1/images/generations/abc123def456 \
      -H "Authorization: Bearer pxr_live_..."
    json
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "abc123def456",
      "status": "success",
      "model": "gpt-image-2",
      "output_urls": [
        "https://42ka.cn/assets/pixora-assets/generations/.../abc.png"
      ],
      "error_message": null,
      "credits_used": 100,
      "duration_ms": 24135,
      "created_at": "2026-05-13T08:32:01.234Z",
      "completed_at": "2026-05-13T08:32:25.369Z"
    }

2. 鉴权 (API Key)

所有 /api/v1/* 端点要求 HTTP Bearer 鉴权, header 形如:

Authorization: Bearer pxr_live_<43 chars>

Key 格式以 pxr_live_ 开头, 后跟 32 字节随机数据(base64url 编码)。如果泄露,/settings可立即撤销。撤销立即生效,使用该 key 的所有正在进行的轮询将开始返回 401。

每个账号最多 10 个未撤销的 key。 已撤销的 key 不计入限额,但保留在 list 中用于审计。

3. 端点

POST /api/v1/images/generations

提交一次新的图像生成任务。请求体:

字段类型说明
promptstring必填,1-4000 字符
modelstring可选,默认 gpt-image-2。可用模型见 /pricing
aspect_ratiostring可选,默认 "1:1"。支持 1:1 / 4:3 / 3:4 / 16:9 / 9:16 / 21:9 / 3:2 / 2:3
num_imagesint可选,默认 1,最大 4
negative_promptstring可选,最多 500 字符

响应 (202 Accepted):

json
{
  "id": "<generation-id>",
  "status": "pending",
  "poll_url": "/api/v1/images/generations/<id>",
  "credits_charged": <int>
}

GET /api/v1/images/generations/:id

查询任务状态。返回:

json
{
  "id": "<generation-id>",
  "status": "pending" | "running" | "success" | "failed" | "cancelled",
  "model": "<model-id>",
  "output_urls": ["https://..."] | null,
  "error_message": "..." | null,
  "credits_used": <int>,
  "duration_ms": <int> | null,
  "created_at": "<ISO 8601>",
  "completed_at": "<ISO 8601>" | null
}

POST /api/v1/images/edits

图像到图像编辑。gpt-image-2 走 OpenAI 原生/v1/images/edits 端点,完整保留源图构图、文字渲染准确。

bash
curl https://42ka.cn/api/v1/images/edits \
  -H "Authorization: Bearer pxr_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "source_image_url": "https://42ka.cn/assets/.../original.png",
    "prompt": "Add bold red text \"SALE\" in the top right corner",
    "model": "gpt-image-2"
  }'

请求体:

字段类型说明
source_image_urlstring必填,必须 https://,最大 25MB
promptstring必填,编辑指令
modelstring可选,默认 gpt-image-2;nano-banana-pro 更便宜但质量差
num_images / aspect_ratio / negative_prompt同 /generations

响应同 /generations(202 + id + poll_url),用同一个 GET 端点轮询。

POST /api/v1/images/batch

一次提交多个不同的 prompt。最多 20 个/请求。每个 prompt 独立计 quota、独立扣积分。 其中任意一个超 quota 或积分不足,整批失败(原子性)。

bash
curl https://42ka.cn/api/v1/images/batch \
  -H "Authorization: Bearer pxr_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "generations": [
      { "prompt": "A red apple", "model": "gpt-image-2" },
      { "prompt": "A green pear", "model": "gpt-image-2" },
      { "prompt": "A yellow banana", "aspect_ratio": "9:16" }
    ]
  }'

响应 (202 Accepted):

json
{
  "generations": [
    { "id": "abc123...", "poll_url": "/api/v1/images/generations/abc123..." },
    { "id": "def456...", "poll_url": "/api/v1/images/generations/def456..." },
    { "id": "ghi789...", "poll_url": "/api/v1/images/generations/ghi789..." }
  ],
  "total_credits_charged": 300
}

GET /api/v1/usage

程序化拉取本账号近期用量统计 — 总数、按天序列、按模型 breakdown、当前余额。 适合做客户侧的成本看板、按月对账等。

bash
curl 'https://42ka.cn/api/v1/usage?days=14' \
  -H "Authorization: Bearer pxr_live_..."
json
{
  "days": 14,
  "summary": {
    "total_generations": 47,
    "total_credits_spent": 4700,
    "total_failures": 2,
    "failure_rate": 0.0425,
    "by_model": {
      "gpt-image-2": { "count": 43, "credits": 4300 },
      "nano-banana-pro": { "count": 4, "credits": 100 }
    }
  },
  "series": [
    { "day": "2026-04-30", "generation_count": 3, "credits_spent": 300, "failure_count": 0 },
    ...
  ],
  "balance": {
    "subscription": 2800,
    "topup": 500,
    "total": 3300
  }
}

查询参数: days (1-90,默认 14)。系列按时间倒序逆排,数组长度 = days,空白天自动填零。

4. 错误码

所有错误响应统一形如:

json
{
  "error": "<machine-readable-code>",
  "message": "<human-readable-detail>"
}
HTTPerror说明
400invalid_request请求体不符合 schema(字段类型、长度等)
400prompt_rejected触发内容过滤(CSAM / 武器合成 / 自残指南 等)
401unauthorized缺失或无效的 API key
402insufficient_credits账户积分不足。充值或升级
404not_found轮询了不存在的任务 id(或属于其他账号)
429rate_limit_exceeded超过每日生成限额(默认 100/天/账号)
500internal_error服务端异常。请重试,持续失败请联系 feedback@42ka.cn

5. 代码示例

Node.js (fetch)

javascript
import fetch from 'node-fetch'

const API_KEY = process.env.PIXORA_API_KEY
const BASE = 'https://42ka.cn/api/v1'

async function generate(prompt) {
  // Submit
  const res = await fetch(`${BASE}/images/generations`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ prompt, model: 'gpt-image-2' }),
  })
  if (!res.ok) throw new Error(`HTTP ${res.status}`)
  const { id } = await res.json()

  // Poll until terminal
  for (;;) {
    await new Promise(r => setTimeout(r, 5000))
    const status = await fetch(`${BASE}/images/generations/${id}`, {
      headers: { 'Authorization': `Bearer ${API_KEY}` },
    }).then(r => r.json())
    if (['success', 'failed', 'cancelled'].includes(status.status)) {
      return status
    }
  }
}

const result = await generate('A red apple on white background')
console.log(result.output_urls[0])

Python (requests)

python
import os
import time
import requests

API_KEY = os.environ['PIXORA_API_KEY']
BASE = 'https://42ka.cn/api/v1'
HEADERS = {'Authorization': f'Bearer {API_KEY}'}

def generate(prompt: str) -> dict:
    r = requests.post(
        f'{BASE}/images/generations',
        headers={**HEADERS, 'Content-Type': 'application/json'},
        json={'prompt': prompt, 'model': 'gpt-image-2'},
    )
    r.raise_for_status()
    gen_id = r.json()['id']

    while True:
        time.sleep(5)
        s = requests.get(f'{BASE}/images/generations/{gen_id}', headers=HEADERS).json()
        if s['status'] in ('success', 'failed', 'cancelled'):
            return s

result = generate('A red apple on white background')
print(result['output_urls'][0])

6. 限额与配额

  • 每账号每日生成上限: 100 张(超额返 429,次日 UTC 凌晨重置)
  • 每账号 API Key 数量: 最多 10 个未撤销
  • 单次请求最多 4 张图(num_images ≤ 4)
  • Prompt 长度: 1-4000 字符
  • 失败的生成会自动退还积分(通常 60s 内)

7. Webhooks (事件回调)

相比轮询,webhook 让 Pixora 在任务完成的瞬间主动 POST 到你的服务, 延迟更低、调用更少。

7.1 创建订阅

/settings → "Webhooks" 区域点 "创建 webhook",填入接收 URL(必须 https://)和订阅的事件类型。 创建后返回 仅显示一次的 signing secret(以whsec_ 开头), 立即复制保存到你的后端环境变量。

7.2 支持的事件

事件名触发时机
generation.completed一次生成进入终态(success / failed / cancelled)

7.3 Payload 示例

json
{
  "event": "generation.completed",
  "generation": {
    "id": "abc123def456",
    "status": "success",
    "model": "gpt-image-2",
    "output_urls": ["https://42ka.cn/assets/..."],
    "credits_used": 100,
    "duration_ms": 24135,
    "created_at": "2026-05-13T08:32:01.234Z",
    "completed_at": "2026-05-13T08:32:25.369Z"
  }
}

7.4 签名验证

每次 POST 都带 X-Pixora-Signature header,格式 t=<unix-ts>,v1=<hex>。 签名内容是 ${ts}.${rawBody} 的 HMAC-SHA256(用你的 signing secret)。 务必在接收端验证,防止伪造:

javascript
import crypto from 'crypto'

function verifyWebhook(signatureHeader, rawBody, secret) {
  // signatureHeader: "t=1715587921,v1=abc123..."
  const parts = Object.fromEntries(
    signatureHeader.split(',').map((p) => p.split('='))
  )
  const ts = parts.t
  const expected = crypto.createHmac('sha256', secret)
    .update(`${ts}.${rawBody}`)
    .digest('hex')
  // Reject if timestamp too old (5 min skew tolerance)
  if (Math.abs(Date.now()/1000 - parseInt(ts)) > 300) return false
  // Constant-time compare to avoid timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(parts.v1, 'hex'),
    Buffer.from(expected, 'hex')
  )
}

7.5 投递重试 + 自动暂停

  • 非 2xx 响应自动重试,最多 3 次,指数退避(1s / 8s / 64s)
  • 连续 10 次失败的订阅自动暂停;在 /settings 手动恢复(会重置失败计数)
  • 每条投递记录(成功/失败/重试)永久保留在 /settings 的展开列表里,可查响应正文片段(前 2KB)
  • 请求 timeout 10s — 你的接收 endpoint 应该立即 200,后台再做业务处理

7.6 接收端最佳实践

  • 幂等 — 网络抖动可能导致同一 delivery_id 重复送达,用 X-Pixora-Delivery-Id header 做去重
  • 快速 ACK — 接收 endpoint 应立即返回 2xx,后台再处理业务,避免 10s timeout 触发重试
  • secret 保密 — 只存在后端环境变量,不要写入前端或 commit 进 git
  • 事件白名单 — 不要订阅你不需要的事件,减少投递压力

8. 路线图

V1 API 已经覆盖了核心场景。下一步排期上的:

  • Per-key 速率限制 — 当前每日上限是按账号粒度,未来可按 key 维度精细管理(便于把生产 key 和开发 key 分开计算)
  • 视频生成 — Kling / Hailuo / Veo 模型对外开放 API
  • Async webhooks for retries — webhook 重试目前是 worker 内存,未来移到独立队列保证重启不丢
  • SDK — 官方 Node + Python SDK,自动处理鉴权 / 轮询 / webhook 验签

有强烈需求的端点?发邮件到 feedback@42ka.cn 告诉我们,优先级上排。

    API Reference — Pixora | Pixora