Errors

Get an API key

Every error answers with an HTTP status and the same JSON envelope. code is the contract your code reads; message is written for a human and may change.

json
{
  "error": {
    "code": "invalid_request",
    "message": "The request is invalid",
    "details": [
      { "field": "targets[0].text", "code": "required", "message": "targets[0].text is required" }
    ],
    "docUrl": "https://www.sofia-post.com/developers/errors#invalid_request",
    "requestId": "2aab5943-6333-4caf-8478-25a85ebd4abf"
  }
}
  • details says more: the refused field, the reason of a network, the exhausted rate window.
  • docUrl leads to the explanation of the code on this page.
  • requestId identifies the request: give it to support.

Error codes

StatusCodeMeaning
400invalid_requestThe body, the query or a parameter is invalid. One detail per refused field: field, code (required, is_string, max…) and message.
400invalid_jsonThe body is not valid JSON.
400invalid_cursorThe cursor was not returned by Sofia API.
400webhook_url_invalidThe webhook address is not https, or leads to a private address.
400webhook_event_invalidUnknown webhook event.
400application_name_invalidSettings › API: the name of the client is missing or too long.
400application_profile_invalidSettings › API: a field of the client profile is invalid; the detail names it.
400logo_invalidSettings › API: the logo is refused (at least 180×180 px, PNG, JPEG or WebP, 2 MB at most).
401invalid_tokenThe token is missing, unknown, expired or revoked, or the person behind it lost the rights it carries. See the WWW-Authenticate header.
401unauthorizedAuthentication is required.
402subscription_requiredA live write (dry run included) needs an active subscription or trial.
403insufficient_scopeThe token lacks the scope of the endpoint; the detail names it.
403insufficient_roleYour role in this Workspace does not allow this action.
403live_mode_requiredA real write with a test token.
403route_closed_to_applicationsThis endpoint is not open to applications.
403forbiddenAccess is refused.
403session_requiredSettings › API: this action needs a Sofia session, not a token.
403impersonation_forbiddenSettings › API: this action is refused in a borrowed session.
403workspace_owner_requiredOnly the owner of the Workspace can do this.
403workspace_member_requiredYou are not a member of this Workspace.
404route_not_foundNo endpoint answers this method and path.
404establishment_not_foundUnknown establishment, or out of reach of the token.
404media_not_foundUnknown media, or out of reach of the token.
404post_not_foundUnknown post, or out of reach of the token.
404webhook_not_foundUnknown webhook, or one of another application.
404not_foundThe resource does not exist.
404application_not_foundSettings › API: unknown client.
404grant_not_foundUnknown authorization, or already revoked.
404personal_key_not_foundSettings › API: unknown personal key.
405method_not_allowedThis method is not allowed on this endpoint.
409post_in_flightA network is sending the post: retry the deletion a moment later.
409post_not_editableA network already sent the post: it can no longer be edited.
409account_already_connectedThis network is already connected to the establishment.
409webhook_limit_reachedThe application already has 10 webhooks.
409idempotency_in_progressThe first request with this Idempotency-Key is still running.
409conflictThe request conflicts with the current state of the resource.
409scope_removal_forbiddenSettings › API: a permission of a client can be added but not removed.
409public_client_has_no_secretSettings › API: a public client has no secret.
413payload_too_largeThe file is above the upload limit.
415unsupported_media_typeUnsupported content type.
422post_refusedA network, the establishment or your plan would refuse the post. One detail per reason, each with its message.
422media_import_refusedThe media could not be imported from this URL; the detail gives the reason.
422media_upload_refusedThe uploaded file is not a supported image or video.
422platform_not_offeredThis network is not offered for connection.
422idempotency_key_reusedThis Idempotency-Key was used with a different body.
422unprocessable_entityThe request is understood but cannot be processed.
429rate_limit_exceededA rate limit window is full: wait for Retry-After.

Reasons of a refused post

A post_refused lists each reason in details[].code:

CodeMeaning
unsupported_platformThis network is not supported.
duplicate_platformThe same network is named twice.
unsupported_formatThis network does not offer this format.
caption_too_longThe text is too long (max, actual).
too_many_hashtagsToo many hashtags (max, actual).
too_many_mentionsToo many mentions (max, actual).
too_many_thread_postsThe thread is too long (max, actual).
too_many_mediaToo many media (max, actual).
media_mix_refusedPhotos and videos cannot be mixed on this network.
media_requiredThis network needs a photo or a video.
media_type_refusedThis network does not accept this type of media.
scheduled_in_pastscheduledAt is in the past.
scheduled_at_invalidA scheduled post needs a future scheduledAt.
account_not_connectedNo account connected on this network for this establishment.
account_ambiguousSeveral accounts are connected on this network: name one with accountId.
media_not_foundThe media is not in the library of this establishment.
media_url_invalidThe media URL must be a public https address.
platform_unavailableThis network is not open on Sofia yet.
publication_quota_exceededThe publication quota of your plan is reached.

Handling errors

  • Branch on code, never on message.
  • Retry 429 after Retry-After, and 5xx with an exponential backoff.
  • Never retry a 4xx unchanged: fix the request first.
  • Log requestId with every failure.