Send to Finalize (step 3 of 4)
const url = 'https://api.tradecrafthub.ai/v1/assessments/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/review-complete';const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.tradecrafthub.ai/v1/assessments/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/review-complete \ --header 'Authorization: Bearer <token>'Reviewer. User-delegated tokens only — a machine client gets 403.
Scope assessments:review (Send to Finalize; lowest role reviewer; user-delegated only). Effective access is the token’s scopes ∩ the caller’s current role.
Idempotency-Key optional: a retry with the same key and request replays the stored response (Idempotent-Replayed: true); another request with the key is 409 IDEMPOTENCY_CONFLICT.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Assessment id
Header Parameters
Section titled “Header Parameters”Your correlation id (8–128 of A–Z a–z 0–9 . _ : -); echoed back
1–255 visible ASCII characters; kept 24 h per (organization, principal, operation)
Responses
Section titled “Responses”Reviewed
object
object
Example generated
{ "data": { "status": "example", "flaggedForApprover": 1, "unanswered": 1 }}Headers
Section titled “Headers”Echoes a valid X-Request-Id, else generated
Requests allowed in the tightest window
Requests left
Seconds until the window resets
UNAUTHENTICATED— No valid session, API key or bearer token.
Missing, unknown, expired or revoked token, or a token for another resource (WWW-Authenticate: Bearer … names the resource metadata).
object
object
The error-code catalogue: VALIDATION_ERROR 400, UNAUTHENTICATED 401, SPEND_CAP_EXCEEDED 402, TENANT_AI_BUDGET_EXCEEDED 402, FORBIDDEN 403, NOT_FOUND 404, CONFLICT 409, GONE 410, ENDPOINT_REMOVED 410, PAYLOAD_TOO_LARGE 413, UNSUPPORTED_MEDIA_TYPE 415, RATE_LIMITED 429, INTERNAL 500, PROVIDER_ERROR 502, SERVICE_UNAVAILABLE 503, WEAK_PASSWORD 400, INVALID_TOKEN 400, EXPIRED_TOKEN 400, INVALID_CREDENTIALS 401, INVALID_CODE 401, SSO_REQUIRED 403, SLUG_TAKEN 409, LAST_ADMIN 409, MANAGED_BY_IDP 409, LOCKED 429, ASSET_KIND_NOT_ALLOWED 400, ASSET_SOURCE_NOT_ALLOWED 400, LIBRARY_ARCHIVED 409, MISSING_SCOPES 400, CLASSIC_TOKEN 400, INVALID_CREDENTIAL 400, CLOUD_ID_UNRESOLVED 400, SITE_NOT_FOUND 400, INTEGRATION_AUTH 409, INTEGRATION_NOT_CONNECTED 409, SITE_CHOICE_EXPIRED 409, PLATFORM_NOT_CONFIGURED 503, PLAN_LIMIT_REACHED 403, PLAN_FEATURE_UNAVAILABLE 403, TRIAL_EXPIRED 403, INSUFFICIENT_SCOPE 403, API_DISABLED 403, IDEMPOTENCY_CONFLICT 409. Extensible.
Human-readable message
INSUFFICIENT_SCOPE: the scope the operation needs
FORBIDDEN: why (member_inactive, permission_missing, not_opted_in, user_only, role, …)
object
Examples
No valid session, API key or bearer token.
{ "error": { "code": "UNAUTHENTICATED", "message": "The access token is invalid, expired or revoked" }}FORBIDDEN— Authenticated, but the role, object grant or policy does not allow this.INSUFFICIENT_SCOPE— The access token lacks the scope this operation needs (error.scope names it; WWW-Authenticate: Bearer error=“insufficient_scope”).API_DISABLED— The organization has turned the API off (Admin → API → Settings); its clients and grants are kept.PLAN_FEATURE_UNAVAILABLE— The organization’s plan does not include this feature (error.feature, plan).TRIAL_EXPIRED— The trial ended (or the subscription was cancelled); the organization is read-only (error.trialEndedAt).
object
object
The error-code catalogue: VALIDATION_ERROR 400, UNAUTHENTICATED 401, SPEND_CAP_EXCEEDED 402, TENANT_AI_BUDGET_EXCEEDED 402, FORBIDDEN 403, NOT_FOUND 404, CONFLICT 409, GONE 410, ENDPOINT_REMOVED 410, PAYLOAD_TOO_LARGE 413, UNSUPPORTED_MEDIA_TYPE 415, RATE_LIMITED 429, INTERNAL 500, PROVIDER_ERROR 502, SERVICE_UNAVAILABLE 503, WEAK_PASSWORD 400, INVALID_TOKEN 400, EXPIRED_TOKEN 400, INVALID_CREDENTIALS 401, INVALID_CODE 401, SSO_REQUIRED 403, SLUG_TAKEN 409, LAST_ADMIN 409, MANAGED_BY_IDP 409, LOCKED 429, ASSET_KIND_NOT_ALLOWED 400, ASSET_SOURCE_NOT_ALLOWED 400, LIBRARY_ARCHIVED 409, MISSING_SCOPES 400, CLASSIC_TOKEN 400, INVALID_CREDENTIAL 400, CLOUD_ID_UNRESOLVED 400, SITE_NOT_FOUND 400, INTEGRATION_AUTH 409, INTEGRATION_NOT_CONNECTED 409, SITE_CHOICE_EXPIRED 409, PLATFORM_NOT_CONFIGURED 503, PLAN_LIMIT_REACHED 403, PLAN_FEATURE_UNAVAILABLE 403, TRIAL_EXPIRED 403, INSUFFICIENT_SCOPE 403, API_DISABLED 403, IDEMPOTENCY_CONFLICT 409. Extensible.
Human-readable message
INSUFFICIENT_SCOPE: the scope the operation needs
FORBIDDEN: why (member_inactive, permission_missing, not_opted_in, user_only, role, …)
object
Examples
Authenticated, but the role, object grant or policy does not allow this.
{ "error": { "code": "FORBIDDEN", "message": "Your current role can't do this", "reason": "role" }}The access token lacks the scope this operation needs (error.scope names it; WWW-Authenticate: Bearer error="insufficient_scope").
{ "error": { "code": "INSUFFICIENT_SCOPE", "message": "This operation needs the assessments:review scope", "scope": "assessments:review" }}The organization has turned the API off (Admin → API → Settings); its clients and grants are kept.
{ "error": { "code": "API_DISABLED", "message": "The API is turned off for this organization. Ask an admin to turn it on in Admin → API." }}The organization's plan does not include this feature (error.feature, plan).
{ "error": { "code": "PLAN_FEATURE_UNAVAILABLE", "message": "The Tradecraft API is not included in your Pro plan. Available on Enterprise.", "feature": "api.rest", "plan": "pro" }}The trial ended (or the subscription was cancelled); the organization is read-only (error.trialEndedAt).
{ "error": { "code": "TRIAL_EXPIRED", "message": "Your trial ended on 2026-11-30. The organization is read-only — upgrade to keep working.", "trialEndedAt": "2026-11-30T00:00:00.000Z" }}NOT_FOUND— No such resource in this organization (unknown, malformed or other-tenant id).
Unknown, malformed or another organization’s id.
object
object
The error-code catalogue: VALIDATION_ERROR 400, UNAUTHENTICATED 401, SPEND_CAP_EXCEEDED 402, TENANT_AI_BUDGET_EXCEEDED 402, FORBIDDEN 403, NOT_FOUND 404, CONFLICT 409, GONE 410, ENDPOINT_REMOVED 410, PAYLOAD_TOO_LARGE 413, UNSUPPORTED_MEDIA_TYPE 415, RATE_LIMITED 429, INTERNAL 500, PROVIDER_ERROR 502, SERVICE_UNAVAILABLE 503, WEAK_PASSWORD 400, INVALID_TOKEN 400, EXPIRED_TOKEN 400, INVALID_CREDENTIALS 401, INVALID_CODE 401, SSO_REQUIRED 403, SLUG_TAKEN 409, LAST_ADMIN 409, MANAGED_BY_IDP 409, LOCKED 429, ASSET_KIND_NOT_ALLOWED 400, ASSET_SOURCE_NOT_ALLOWED 400, LIBRARY_ARCHIVED 409, MISSING_SCOPES 400, CLASSIC_TOKEN 400, INVALID_CREDENTIAL 400, CLOUD_ID_UNRESOLVED 400, SITE_NOT_FOUND 400, INTEGRATION_AUTH 409, INTEGRATION_NOT_CONNECTED 409, SITE_CHOICE_EXPIRED 409, PLATFORM_NOT_CONFIGURED 503, PLAN_LIMIT_REACHED 403, PLAN_FEATURE_UNAVAILABLE 403, TRIAL_EXPIRED 403, INSUFFICIENT_SCOPE 403, API_DISABLED 403, IDEMPOTENCY_CONFLICT 409. Extensible.
Human-readable message
INSUFFICIENT_SCOPE: the scope the operation needs
FORBIDDEN: why (member_inactive, permission_missing, not_opted_in, user_only, role, …)
object
Examples
No such resource in this organization (unknown, malformed or other-tenant id).
{ "error": { "code": "NOT_FOUND", "message": "Not found" }}CONFLICT— The resource’s state does not allow this now (wrong lifecycle state, duplicate, already running).IDEMPOTENCY_CONFLICT— The Idempotency-Key was already used for a different request, or the first request with it is still running.
object
object
The error-code catalogue: VALIDATION_ERROR 400, UNAUTHENTICATED 401, SPEND_CAP_EXCEEDED 402, TENANT_AI_BUDGET_EXCEEDED 402, FORBIDDEN 403, NOT_FOUND 404, CONFLICT 409, GONE 410, ENDPOINT_REMOVED 410, PAYLOAD_TOO_LARGE 413, UNSUPPORTED_MEDIA_TYPE 415, RATE_LIMITED 429, INTERNAL 500, PROVIDER_ERROR 502, SERVICE_UNAVAILABLE 503, WEAK_PASSWORD 400, INVALID_TOKEN 400, EXPIRED_TOKEN 400, INVALID_CREDENTIALS 401, INVALID_CODE 401, SSO_REQUIRED 403, SLUG_TAKEN 409, LAST_ADMIN 409, MANAGED_BY_IDP 409, LOCKED 429, ASSET_KIND_NOT_ALLOWED 400, ASSET_SOURCE_NOT_ALLOWED 400, LIBRARY_ARCHIVED 409, MISSING_SCOPES 400, CLASSIC_TOKEN 400, INVALID_CREDENTIAL 400, CLOUD_ID_UNRESOLVED 400, SITE_NOT_FOUND 400, INTEGRATION_AUTH 409, INTEGRATION_NOT_CONNECTED 409, SITE_CHOICE_EXPIRED 409, PLATFORM_NOT_CONFIGURED 503, PLAN_LIMIT_REACHED 403, PLAN_FEATURE_UNAVAILABLE 403, TRIAL_EXPIRED 403, INSUFFICIENT_SCOPE 403, API_DISABLED 403, IDEMPOTENCY_CONFLICT 409. Extensible.
Human-readable message
INSUFFICIENT_SCOPE: the scope the operation needs
FORBIDDEN: why (member_inactive, permission_missing, not_opted_in, user_only, role, …)
object
Examples
The resource's state does not allow this now (wrong lifecycle state, duplicate, already running).
{ "error": { "code": "CONFLICT", "message": "Cannot process assessment with status \"uploaded\". Must be \"analyzed\" (run Analyze first)." }}The Idempotency-Key was already used for a different request, or the first request with it is still running.
{ "error": { "code": "IDEMPOTENCY_CONFLICT", "message": "This Idempotency-Key was used for a different request" }}RATE_LIMITED— Too many requests; retry after the Retry-After header.
Retry-After and RateLimit-* tell when to retry.
object
object
The error-code catalogue: VALIDATION_ERROR 400, UNAUTHENTICATED 401, SPEND_CAP_EXCEEDED 402, TENANT_AI_BUDGET_EXCEEDED 402, FORBIDDEN 403, NOT_FOUND 404, CONFLICT 409, GONE 410, ENDPOINT_REMOVED 410, PAYLOAD_TOO_LARGE 413, UNSUPPORTED_MEDIA_TYPE 415, RATE_LIMITED 429, INTERNAL 500, PROVIDER_ERROR 502, SERVICE_UNAVAILABLE 503, WEAK_PASSWORD 400, INVALID_TOKEN 400, EXPIRED_TOKEN 400, INVALID_CREDENTIALS 401, INVALID_CODE 401, SSO_REQUIRED 403, SLUG_TAKEN 409, LAST_ADMIN 409, MANAGED_BY_IDP 409, LOCKED 429, ASSET_KIND_NOT_ALLOWED 400, ASSET_SOURCE_NOT_ALLOWED 400, LIBRARY_ARCHIVED 409, MISSING_SCOPES 400, CLASSIC_TOKEN 400, INVALID_CREDENTIAL 400, CLOUD_ID_UNRESOLVED 400, SITE_NOT_FOUND 400, INTEGRATION_AUTH 409, INTEGRATION_NOT_CONNECTED 409, SITE_CHOICE_EXPIRED 409, PLATFORM_NOT_CONFIGURED 503, PLAN_LIMIT_REACHED 403, PLAN_FEATURE_UNAVAILABLE 403, TRIAL_EXPIRED 403, INSUFFICIENT_SCOPE 403, API_DISABLED 403, IDEMPOTENCY_CONFLICT 409. Extensible.
Human-readable message
INSUFFICIENT_SCOPE: the scope the operation needs
FORBIDDEN: why (member_inactive, permission_missing, not_opted_in, user_only, role, …)
object
Examples
Too many requests; retry after the Retry-After header.
{ "error": { "code": "RATE_LIMITED", "message": "Too many requests — retry after the Retry-After header" }}