Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sdk.anghami.com/llms.txt

Use this file to discover all available pages before exploring further.

The SDK returns one of two structured envelopes for every failure: a ValidationError for request-shape failures (HTTP 400) and a generic Error for everything else. Both shapes are declared in the bundled OpenAPI spec.

Validation errors (HTTP 400)

When a request fails buf.validate checks or has malformed JSON, the response is:
{
  "violations": [
    { "field": "song_id.value", "description": "value is required" },
    { "field": "pageSize",      "description": "value must be between 1 and 100" }
  ]
}
FieldTypeNotes
violationsarray of FieldViolationOne entry per failed field.
violations[].fieldstringDotted JSON path to the field. For header validation this is the header name (e.g. X-API-Key).
violations[].descriptionstringHuman-readable description of what failed.
Branch on the HTTP status (400) and surface violations to the developer. End users almost never see these — they indicate a client-side bug.

Other errors (everything except 400)

For any non-validation failure, the response is a minimal envelope:
{ "message": "song not found" }
message is the only field. Treat it as developer-facing detail; it may include internal context. The discriminator for branching is the HTTP status code, not a field inside the body:
HTTPMeaningWhen
400Validation errorMalformed body or buf.validate failure — body is ValidationError (see above).
401UnauthenticatedMissing/invalid credential (no x-api-key, no/expired Bearer token).
403Permission deniedValid credential but missing scope or unauthorized for the resource.
404Not foundThe targeted entity does not exist or is not visible to this caller.
409ConflictRequest conflicts with current state (e.g. revoking an already-revoked key).
429Rate limitedSee Rate Limits.
500InternalUnexpected server failure. Safe to retry with back-off.
503UnavailableTransient — retry with exponential back-off and jitter.

Batch errors

BatchGetSongs, BatchGetAlbums, BatchGetArtists, BatchGetShows, BatchGetMovies, BatchGetSeasons, and BatchGetEpisodes return a map of ID → result, where each entry is a oneof of either the entity or a BatchItemError. Successful and failed items live side by side in the same response — the top-level call only fails if the request itself is malformed.
{
  "results": {
    "123": { "song":  { "id": { "value": "123" }, "title": { "value": "...", "originalValue": "..." } } },
    "456": { "error": { "code": "ERROR_CODE_NOT_FOUND", "message": "song not found" } }
  }
}
BatchItemError carries code (an ErrorCode enum string — typically ERROR_CODE_NOT_FOUND or ERROR_CODE_PERMISSION_DENIED) and message. Iterate the map, branch on which oneof arm is set, and only fail your overall flow if the failures violate your business rules.

Idempotency and retries

  • All Get*, Batch*, Search, and Browse* operations are idempotent — safe to retry on INTERNAL / UNAVAILABLE.
  • Acquire*Stream is idempotent within the duration of a stream URL — retrying simply returns a fresh URL. Each acquire is the billable event, so don’t retry past the back-off window unnecessarily.
  • CreateApiKey, RotateApiKey, RevokeApiKey are not safely retryable on ambiguous failures. Use ListApiKeys to reconcile state before retrying.