Concepts

Envelope and errors

Every Openhandle response uses one envelope. Every error has a code, a request ID, and a retry rule.

Every successful response wraps its data in the same envelope, and every error returns the same error shape with a machine-readable code and an explicit retry flag. You handle responses once, for every platform and every endpoint.

The success envelope

{
  "platform": "instagram",
  "resource": "profile",
  "capturedAt": "2026-08-06T12:04:11Z",
  "source": "live",
  "data": { "…": "…" },
  "meta": {
    "cursors": { "next": "opaque-cursor" }
  }
}
FieldMeaning
platforminstagram, tiktok, or twitter
resourceprofile, post, comment, hashtag, location, music, category, list, or normalized extended entity
capturedAtRFC 3339 timestamp of when the data was captured
sourcelive (fetched now) or cache (served from an earlier capture)
dataThe normalized resource, or an array of resources for lists
metaOnly on list responses. See pagination

Shared cores and platform schemas

Openhandle reuses schemas only when their meaning is stable across platforms. For example, every post composes the shared PostCore, PostMetrics, PostAuthor, PostMedia, and MediaReference components. The final response is still an InstagramPost, TikTokPost, or TwitterPost, with a matching platform metrics schema and platform-only relationships.

Unavailable values are null; measured zeroes are 0. Platform fields are not discarded merely because another platform lacks an equivalent. TikTok can return metrics.downloads, while Twitter can return metrics.quotes, metrics.bookmarks, quoted_post, and reposted_post. Media keeps a preferred url for simple clients and exposes every usable public rendition in variants when the upstream response supplies alternatives.

Profiles and comments follow the same contract pattern: a shared core plus a platform-specific final schema. Profile extended nodes preserve public fields that exist only on Instagram, TikTok, or Twitter. Domain-specific endpoints use dedicated schemas where the provider data is stable enough—for example, InstagramStory, InstagramHighlight, TikTokPlaylist, and TikTokEffect. Heterogeneous search endpoints use discriminated search-result nodes, and filter/type endpoints use typed option nodes. No published operation falls back to the generic Entity schema. See the generated OpenAPI document for the exact schema attached to each operation.

The error envelope

{
  "error": {
    "code": "PROFILE_NOT_FOUND",
    "message": "This profile was not found.",
    "requestId": "req_01j8…",
    "retryable": false
  }
}

Always branch on code, not on message. Include requestId when you contact support. When retryable is true, retry with backoff; when it is false, retrying will not help.

Error catalog

CodeStatusRetryableMeaning
UNAUTHENTICATED401NoA valid API key is required
EMAIL_VERIFICATION_REQUIRED403NoVerify the workspace-owner email before using Live
PAYMENT_METHOD_REQUIRED402NoAdd a payment method to continue
BILLING_SUSPENDED402NoBilling for this workspace is suspended
SECURITY_SUSPENDED403NoAPI access for this workspace is suspended
PROFILE_NOT_FOUND404NoThe profile does not exist
PROFILE_PRIVATE403NoThe profile is private
POST_NOT_FOUND404NoThe post does not exist
COMMENT_NOT_FOUND404NoThe comment does not exist
INVALID_IDENTIFIER400NoThe identifier is invalid
INVALID_FRESHNESS400NoFreshness must be live, 24h, 7d, or 30d
INVALID_SINCE400Nosince must be an RFC 3339 timestamp
CURSOR_MISMATCH400NoThe cursor does not belong to this request
UPSTREAM_SWITCHED409YesThe upstream source changed. Restart pagination
RATE_LIMITED429YesRate limit exceeded. Honor the Retry-After header
SERVICE_UNAVAILABLE503YesThe service is temporarily unavailable
UPSTREAM_DEGRADED503YesThe upstream platform is temporarily unavailable
INTERNAL_ERROR500YesThe request could not be completed
ROUTE_NOT_FOUND404NoThe API route does not exist
METHOD_NOT_ALLOWED405NoThe HTTP method is not allowed on this route

Billing and errors

You pay for answers, not attempts. PROFILE_NOT_FOUND, PROFILE_PRIVATE, and other definitive answers are billable: the API did the work and gave you a usable result. Provider failures and internal errors are never charged.

On this page