Reference
Error Reference
All Kifly agent endpoints return structured JSON errors:
{
"error": "error_code",
"message": "Human-readable explanation",
"details": {}
}
details contains context specific to the error (e.g. the delivery coverage that rejected the address, or the maximum allowed value that was exceeded).
HTTP status codes
| Status | Meaning | What to do |
|---|---|---|
400 | Bad request — missing or invalid field | Fix the request body; do not retry as-is |
401 | Missing or invalid API key | Check your Authorization: Bearer kfa_live_… header |
402 | Payment required | Follow the MPP challenge-response flow (Rail 3) |
403 | Forbidden — resource mismatch or insufficient scope | Do not retry; check token scopes |
404 | Resource not found | Confirm IDs are correct and owned by this token |
409 | Idempotency conflict — same key, different request body | Use a new Idempotency-Key |
422 | Validation error — semantically invalid | Read details for the specific field |
429 | Rate limit exceeded | Wait for the value in Retry-After |
503 | Upstream dependency temporarily unavailable | Retry after retry_after_seconds |
Error codes
Authentication
| Code | Status | Description |
|---|---|---|
invalid_api_key | 401 | The Bearer token is not recognized |
api_key_revoked | 401 | The token exists but has been revoked |
missing_idempotency_key | 400 | Idempotency-Key header is required on mutating endpoints |
idempotency_conflict | 409 | Same key used with a different request body |
scope_insufficient | 403 | Token lacks the required scope (e.g. checkout:write) |
Cart
| Code | Status | Description |
|---|---|---|
cart_not_found | 404 | No cart with the given ID under your token |
cart_locked | 409 | Checkout is already in progress; wait and retry |
cart_already_completed | 409 | The cart was already purchased; create a new cart |
item_not_found | 404 | No line item with the given ID in this cart |
quantity_exceeds_limit | 400 | Requested quantity exceeds the platform maximum per line item |
seller_mismatch | 403 | The variant belongs to a different seller than the cart |
Checkout / Payment
| Code | Status | Description |
|---|---|---|
shipping_address_required | 400 | Call set_shipping_address before checkout |
delivery_not_available | 400 | Buyer's address is outside the seller's delivery coverage |
cart_total_exceeds_limit | 400 | Cart total (subtotal + delivery fee) exceeds the platform cap; details.max_cents has the current ceiling |
payment_failed | 402 | SPT verification or Stripe settlement failed |
x402_not_configured | 400 | X-Payment sent but x402 is not activated in this environment |
Upstream
| Code | Status | Description |
|---|---|---|
upstream_unavailable | 503 | A required upstream service is temporarily unreachable |
checkout_engine_unavailable | 503 | Commerce engine unreachable; cart state is safe, retry checkout |
Retry strategy
For 503 responses, use exponential backoff starting from retry_after_seconds:
{
"error": "upstream_unavailable",
"retry_after_seconds": 30
}
For 429, wait for the Retry-After header value. For all other errors, fix the request before retrying.
Always reuse the same Idempotency-Key when retrying — this guarantees exactly-once semantics even if the network drops after the server commits.
Rate limits
| Endpoint | Limit |
|---|---|
/api/mcp | 120 req / 60 s per token |
/api/agent/* | 60 req / 60 s per token |
/api/agent/feedback | 10 req / 60 s per token |
Responses include x-ratelimit-limit, x-ratelimit-remaining, and x-ratelimit-reset headers on every request.