このページはまだ日本語に対応していないため、英語で表示しています。
Reference
Errors and idempotency keys
A failed call is a tool error (isError: true) whose text is JSON:
{ "error": "INVALID_INPUT", "message": "invalid fields", "fields": ["ends_at"] }Arguments that don't match a tool's input schema (a missing field, a value out of range, an unknown enum value such as status: verified_by_human) are INVALID_INPUT too. fields names the inputs to fix as dotted paths (bonus.amount_each, options.1.label) and comes only with INVALID_INPUT; message says what is wrong in English.
| Code | Meaning and what to do |
|---|---|
INVALID_INPUT | An input is missing, out of range or not allowed; fields names which, and message says why when that is known (e.g. an image that isn't valid base64 or isn't a PNG, JPEG or WebP). Fix them and call again. |
NOT_FOUND | No such app, mission, build or feedback in the apps this connection may use (other apps look the same as missing ones), or no tool with that name. |
FORBIDDEN | The connection doesn't allow this scope on that app, may not create apps, or was revoked (then connect again), or the account is suspended. |
SUBSCRIPTION_REQUIRED | The account has no active Indie or Team plan. Choose one at pumati.app/dev/credits. |
INVALID_STATE | The mission isn't in a state that allows this, e.g. publishing one that is already published. |
DRAFT_CHANGED | The draft changed since expected_revision. Read it again with get_test and publish with the new revision. |
REVISION_CHANGED | The feedback was revised since the revision_no you reviewed. Read it again with get_feedback and review the new revision. |
CLAIMED | A Pumati reviewer is working on this feedback right now. Try again later or leave it to them. |
SPEND_LIMIT | The budget doesn't fit in what is left of this connection's spend limit. Raise it by reconnecting, or publish smaller. |
INSUFFICIENT_CREDITS | The app owner's balance can't cover the budget. Buy credits at pumati.app/dev/credits. |
BUILD_REQUIRED | A targeted platform has no linked build. Register one and link it in build_ids. |
BUILD_NOT_APPROVED | A linked iOS build is still waiting for Apple's beta review. |
BUILD_EXPIRES_TOO_SOON | A linked build expires before the mission ends. End earlier or link a newer build. |
IDEMPOTENCY_MISMATCH | This idempotency_key was used with different input. Use a new key. |
IDEMPOTENCY_NOT_GRANTED | This key created an app this connection can't use. Use a new key. |
INTERNAL | Something went wrong on our side. Retry with the same idempotency_key. |
Idempotency keys
Every write and publish tool takes an optional idempotency_key: 1 to 128 characters of A-Z a-z 0-9 . _ : -. A key is scoped to your account and the OAuth client that sends it: the same key from a different client (Codex after Claude Code, say) is a new request and creates a new resource. Signing in again with the same client keeps its keys; a client that registers anew (for example after removing and re-adding the server) counts as a different client.
- The same key with the same input returns the first result without doing it again, so a retry after a timeout never publishes twice.
- The same key with different input is
IDEMPOTENCY_MISMATCH: use a new key for a new request. - A call that failed stores nothing, so you can retry it with the same key.
- Concurrent calls with one key wait for the first and return its result.
Use a key that describes the intent, e.g. publish-<mission_id>-<revision>.
Draft revisions
Drafts carry a draft_revision. publish_test takes the revision you last saw as expected_revision; if someone edited the draft since (on the web, for example) it fails with DRAFT_CHANGED. Call get_test, check the draft, and publish with the new revision.