Error Response Format
All platform API errors return a consistent JSON envelope:
{
"error": {
"code": "platform_invalid_request",
"message": "Validation failed: questionText is required",
"status": 400
}
}The error.code is a machine-readable identifier you can use in your error handling logic.
Error Codes
| Code | HTTP Status | Meaning |
|---|---|---|
platform_invalid_request | 400 | Invalid request body or parameters |
platform_invalid_api_key | 401 | Missing or invalid API key |
platform_api_key_revoked | 401 | API key has been revoked |
platform_api_key_expired | 401 | API key has expired |
platform_forbidden | 403 | API key doesn't have access to this resource |
email_verification_required | 403 | Workspace email has not been verified |
free_credits_exhausted | 403 | Free credits used up and no payment method registered |
payment_required | 402 | Credits exhausted; pay with USDC via x402 or register a payment method |
x402_payment_failed | 402 | USDC payment verification failed |
platform_workspace_suspended | 403 | Workspace is suspended |
platform_not_found | 404 | Resource doesn't exist |
platform_rate_limit_exceeded | 429 | Rate limit exceeded |
platform_insufficient_credits | 402 | Insufficient credits |
platform_internal_error | 500 | Something went wrong on our end |
HTTP Status Codes
| Code | Meaning | When |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
400 | Bad Request | Invalid request body or parameters |
401 | Unauthorized | Missing, invalid, revoked, or expired API key |
402 | Payment Required | Insufficient credits |
403 | Forbidden | Workspace suspended or access denied |
404 | Not Found | Resource doesn't exist |
409 | Conflict | Resource already exists (e.g. duplicate slug) |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Something went wrong on our end |
Common Errors
Invalid API Key
{
"error": {
"code": "platform_invalid_api_key",
"message": "Invalid or missing API key",
"status": 401
}
}Check that your Authorization header uses the correct format: Bearer tf_platform_...
Workspace Suspended
{
"error": {
"code": "platform_workspace_suspended",
"message": "Workspace is suspended",
"status": 403
}
}Contact support to reactivate your workspace.
Email Verification Required
{
"error": {
"code": "email_verification_required",
"message": "Workspace email has not been verified",
"status": 403
}
}Verify the workspace email address before making API calls. A verification email is sent
at registration. If it did not arrive, call POST /v1/platform/agent/verify-email/resend
to request a new one.
Free Credits Exhausted
{
"error": {
"code": "free_credits_exhausted",
"message": "Your free credits have been exhausted. Register a payment method or purchase additional credits to continue. Call POST /v1/platform/agent/billing/session to get started.",
"status": 403
}
}New workspaces receive $1.00 in free credits. Once exhausted, register a payment method via
POST /v1/platform/agent/billing/session and purchase additional credits to continue.
Payment Required (x402)
{
"error": {
"code": "payment_required",
"message": "Credits exhausted. Pay with USDC via x402 or register a payment method.",
"x402": {
"scheme": "exact",
"network": "eip155:8453",
"price": "$0.01",
"payTo": "0x...",
"description": "TutorFlow API request payment",
"mimeType": "application/json",
"resource": "POST /v1/platform/evaluations"
},
"billingSessionUrl": "POST /v1/platform/agent/billing/session",
"status": 402
}
}When you receive a 402 response, you have two options:
- Pay with USDC: Send USDC to the
payToaddress on the specified network, then retry with theX-Paymentheader. - Register a card: Call
POST /v1/platform/agent/billing/sessionto get a checkout URL for card-based payment.
Insufficient Credits
{
"error": {
"code": "platform_insufficient_credits",
"message": "Insufficient credits",
"status": 402
}
}Add credits to your workspace or upgrade your plan.
Rate Limit Exceeded
{
"error": {
"code": "platform_rate_limit_exceeded",
"message": "Rate limit exceeded",
"status": 429
}
}Wait and retry with exponential backoff. See Rate Limiting.
Best Practices
- Always check
error.codefor programmatic error handling. - Log
error.messagefor debugging. It may contain specific field-level details. - Implement retry logic with exponential backoff for
429and5xxerrors. - Never retry
4xxerrors (except429). They indicate a client-side issue.