사용 안내서
Content Integration Errors

Content Integration Errors

Understand Content Integration error codes, retry rules, and support handoff details.

Content Integration errors use a stable error.code value. Treat the code as the client-facing contract and the message as human-readable detail.

Error codes

CodeMeaningRetry
content_invalid_api_keyBearer token is missing, malformed, revoked, or expired.No. Create or rotate the key.
content_invalid_requestRequest body failed validation.No. Fix the payload.
content_forbiddenSigned-in admin cannot manage the target organization.No. Use an admin with access.
content_not_foundJob, key, webhook, classroom, content resource, or game or simulation version was not found.No, unless the id was mistyped.
content_conflictRequest conflicts with an existing state, or an idempotency key was reused with different request content.Usually no. Check idempotency.
content_payment_requiredThe organization does not have enough availableCredit for the requested expansion outputs or for a game or simulation brief, build, or revise. HTTP 402.Not until credits are added.
content_payment_failedThe organization's payment has failed. HTTP 402.Not until billing is resolved in TutorFlow.
content_rate_limit_exceededKey rate limit was exceeded.Yes, after waiting.
content_internal_errorUnexpected server error.Yes, with backoff.

The two 402 codes are the only errors a caller cannot fix by changing the request. Check GET /v1/content/credits, then add credits or resolve the billing issue before retrying with the same idempotency key. Content API requests never fall back to Agent Platform credits.

Example error

{
  "error": {
    "code": "content_invalid_api_key",
    "message": "Invalid or missing Content Integration API key",
    "status": 401
  }
}

Validation errors

Requests rejected by body validation (content_invalid_request) additionally carry error.details: one entry per invalid field with the dotted field path, a readable message, and the failed constraints. Use it to fix a rejected payload programmatically instead of parsing the message string.

{
  "error": {
    "code": "content_invalid_request",
    "message": "Validation failed: sourceTitle must be a string",
    "details": [
      {
        "field": "sourceTitle",
        "message": "sourceTitle must be a string",
        "constraints": ["isString", "isNotEmpty"]
      }
    ],
    "status": 422
  }
}

Router-level 404s under /v1/content/** (for example a typo in the path) use the same envelope with error.code: "content_not_found".

Errors on streaming routes

The game and simulation brief, build, and revise routes answer with text/event-stream. Everything that can be checked up front is checked before the stream opens, and those failures use the JSON envelope above with the matching status: 404 for a missing classroom or resource, 400 for a build without a brief or a revision of an unbuilt resource, 402 for credits.

Once the stream has opened the HTTP status is already 200. A failure after that point arrives as an error event:

event: error
data: {"message":"The safety rules were not satisfied","violations":["Game did not start within 10s"]}

Nothing was stored and nothing was charged. When violations is present the model could not produce a page that passed the checks for that plan, so change the brief or metadata rather than retrying the same build. A closed connection is not an error event: hanging up aborts the build and charges nothing.

Retry rules

  • Retry 429 after waiting at least 30 seconds.
  • Retry 500 with exponential backoff.
  • Do not retry 400 without changing the payload.
  • Do not retry 401 without replacing the key.
  • Do not retry 402 until the organization has enough available AI Credits and payment is active.
  • Retry a build whose stream ended with an error event at most once. If the event carried violations, change the plan first.
  • Do not create a second job for the same source content while the original job is still queued or processing.

Failed jobs

When a job reaches failed, fetch the result endpoint and inspect:

  • job.error
  • each outputs[].error
  • requested output list
  • source title

Fix the source JSON or requested outputs, then create a new job with a new idempotency key if the source content changed.

Support handoff

Send these fields to TutorFlow support:

FieldNotes
jobIdRequired for expansion issues.
Game or simulation id and contentVersionRequired for build, revise, and restore issues.
keyPrefixSafe to share. Do not send the full key.
Endpoint pathExample: /v1/content/integrations/expansions.
TimestampInclude timezone.
Idempotency keyHelps find duplicate or retried requests.
Final response bodyInclude error object and status code.
Source JSON sampleInclude only if it can be shared.