# Read one creator by network and handle

`GET /creators/{network}/{handle}`

Resolves to exactly one of three outcomes: 200 (we hold the document, wrapped as `{ data: <creator> }` — a creator is expressed as its `channels`, always at least one, unordered), 202 (discovery just started — a `fetching` bucket entry; re-read after `Retry-After`), or 404 (not obtainable — an `error` envelope; branch on `details.reason`). Requires `creators:read`.

Full operation definition — parameters, request/response schemas, and examples, fully dereferenced against the OpenAPI document:

```json
{
  "operationId": "getCreatorByHandle",
  "tags": [
    "creators"
  ],
  "summary": "Read one creator by network and handle",
  "description": "Resolves to exactly one of three outcomes: 200 (we hold the document, wrapped as `{ data: <creator> }` — a creator is expressed as its `channels`, always at least one, unordered), 202 (discovery just started — a `fetching` bucket entry; re-read after `Retry-After`), or 404 (not obtainable — an `error` envelope; branch on `details.reason`). Requires `creators:read`.",
  "x-required-scope": "creators:read",
  "parameters": [
    {
      "name": "network",
      "in": "path",
      "required": true,
      "description": "The network to look up the creator on.",
      "schema": {
        "type": "string",
        "enum": [
          "instagram"
        ]
      },
      "examples": {
        "somehandle": {
          "value": "instagram"
        }
      }
    },
    {
      "name": "handle",
      "in": "path",
      "required": true,
      "description": "The creator's handle on that network, without an `@`.",
      "schema": {
        "type": "string"
      },
      "examples": {
        "somehandle": {
          "value": "somehandle"
        }
      }
    },
    {
      "name": "include",
      "in": "query",
      "required": false,
      "description": "Comma-separated additive extras. `posts` attaches the creator's recent posts (core fields only).",
      "schema": {
        "type": "string",
        "enum": [
          "posts"
        ]
      },
      "example": "posts"
    },
    {
      "name": "asOrg",
      "in": "query",
      "required": false,
      "description": "Names a target Organization to act on, when it differs from your credential's own organization — for a delegated agency/partner relationship.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "asProfile",
      "in": "query",
      "required": false,
      "description": "Attribution only — associates this read's discovery/refresh work with one of your Profiles, resolved within your organization.",
      "schema": {
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "We hold the data (and it's fresh enough). The creator document is wrapped as `{ data: <creator> }` — `data.channels` carries this creator's channels (always at least one, unordered — do not read position as significance; today this is always exactly one channel, multi-channel hydration is not yet implemented), and `data.posts` is present only when requested via `include=posts`.",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "channels": {
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "network": {
                          "type": "string",
                          "const": "instagram",
                          "description": "The social network this channel belongs to."
                        },
                        "externalId": {
                          "description": "The channel's network-native identifier (Instagram's numeric user id), stable for the account's lifetime.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "username": {
                          "description": "The channel's current @handle.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "followersCount": {
                          "description": "Total number of followers.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "verified": {
                          "description": "Whether the network has verified this channel's identity. Sourced only from a successful Instagram Creator Marketplace lookup — null for a brand/business account (Creator Marketplace doesn't cover them) or when Creator Marketplace credentials aren't configured for the org.",
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "country": {
                          "description": "The channel's country.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "instagram": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "description": "The account's display name (distinct from `username`).",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "biography": {
                              "description": "The account's bio text.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "website": {
                              "description": "The website URL listed on the account's profile.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "profilePictureUrl": {
                              "description": "URL of the account's current profile picture.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "followsCount": {
                              "description": "Number of accounts this creator follows.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "mediaCount": {
                              "description": "Total number of posts on this account.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "gender": {
                              "description": "The creator's gender, when known. Common values are `male`, `female`, and `unknown` (undisclosed), though other values may appear over time.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "ageBucket": {
                              "description": "The age range the creator belongs to (e.g. `18-24`), or `unknown` when undisclosed. Other ranges may appear over time.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "onboardedStatus": {
                              "description": "Whether the creator has been onboarded to the Creator Marketplace.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "portfolioUrl": {
                              "description": "URL of the creator's Portfolio.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "email": {
                              "description": "Contact email on file for this creator. Not necessarily verified, and no format validation is applied.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "isPaidPartnershipMessagesEnabled": {
                              "description": "Whether the creator has enabled paid partnership messages through the Instagram Creator Marketplace.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "hasBrandPartnershipExperience": {
                              "description": "Whether the creator has branded content or partnership ads collaboration experience in the past year.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "pastBrandPartnershipPartners": {
                              "description": "The brands the creator has collaborated with on branded content or partnership ads in the past year.",
                              "items": {
                                "type": "string"
                              },
                              "type": [
                                "array",
                                "null"
                              ]
                            },
                            "badges": {
                              "description": "The badges of the creator. Meta does not publish a closed or confirmed set of possible values — treat as opaque strings, not an enum.",
                              "items": {
                                "type": "string"
                              },
                              "type": [
                                "array",
                                "null"
                              ]
                            },
                            "reach": {
                              "description": "This account's reach metric (distinct accounts that saw its content).",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "hasProfilePic": {
                              "description": "Whether the account currently has a profile picture set.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "isPublished": {
                              "description": "Whether the account is published.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "creatorEngagedAccounts": {
                              "description": "Number of distinct accounts that engaged with this creator's content.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "reelsInteractionRate": {
                              "description": "Reels interaction rate, as a percentage of reel views (e.g. `7.2` means 7.2%).",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "reelsHookRate": {
                              "description": "Reels hook rate — the percentage of viewers who kept watching past the opening seconds (e.g. `42` means 42%).",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "audienceDemographics": {
                              "description": "Engaged-audience demographics, present only for accounts we hold a live grant with audience-insights scope for. Its internal shape is NOT part of the v1 compatibility promise (D19) — Meta's own payload, passed through opaquely. Meta returns 5 breakdown dimensions: country, city, gender, age, and the combined age,gender. Results may not be exhaustive."
                            }
                          },
                          "required": [
                            "name",
                            "biography",
                            "website",
                            "profilePictureUrl",
                            "followsCount",
                            "mediaCount",
                            "gender",
                            "ageBucket",
                            "onboardedStatus",
                            "portfolioUrl",
                            "email",
                            "isPaidPartnershipMessagesEnabled",
                            "hasBrandPartnershipExperience",
                            "pastBrandPartnershipPartners",
                            "badges",
                            "reach",
                            "hasProfilePic",
                            "isPublished",
                            "creatorEngagedAccounts",
                            "reelsInteractionRate",
                            "reelsHookRate"
                          ]
                        },
                        "updatedAt": {
                          "description": "ISO 8601 timestamp of when this channel's current snapshot was produced — how fresh this document is.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "network",
                        "externalId",
                        "username",
                        "followersCount",
                        "verified",
                        "country",
                        "instagram",
                        "updatedAt"
                      ]
                    },
                    "description": "This creator's channels. Always at least one. UNORDERED — carries no meaningful index; do not read position as significance. Intended to eventually return every channel a creator owns, not only the ones a search filter matched — today this is always exactly one channel; multi-channel hydration is not yet implemented."
                  },
                  "posts": {
                    "description": "This creator's recent posts, included only when the request asked for `?include=posts`. Absent (not empty) when not requested. Posts are not nested per channel — to attribute a post back to one of `channels`, match its `author.accountId` against that channel's `externalId`.",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "network": {
                          "description": "The social network this post is on.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "externalId": {
                          "description": "The post's network-native identifier.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "url": {
                          "description": "The post's public permalink.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "postedAt": {
                          "description": "ISO 8601 timestamp of when the post was published.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "text": {
                          "description": "The post's caption text.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "mediaKind": {
                          "description": "The post's media type — `video`, `image`, or `carousel`.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "likeCount": {
                          "description": "Total like count.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "commentCount": {
                          "description": "Total comment count.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "viewCount": {
                          "description": "Total view count.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "shareCount": {
                          "description": "Total share count.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "saveCount": {
                          "description": "Total save count.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "author": {
                          "type": "object",
                          "properties": {
                            "accountId": {
                              "type": "string",
                              "description": "The post author's network-native account identifier."
                            },
                            "username": {
                              "description": "The post author's @handle.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "followersCount": {
                              "description": "Total number of followers the post author has.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "verified": {
                              "description": "Whether the post author's identity is verified on the network.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "country": {
                              "description": "The post author's country.",
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "accountId",
                            "username",
                            "followersCount",
                            "verified",
                            "country"
                          ],
                          "description": "The post's author — a thin, no-PII summary of the creator account. `author.accountId` is the only way to attribute a post back to one of `Creator.channels` — match it against that channel's `externalId`."
                        }
                      },
                      "required": [
                        "network",
                        "externalId",
                        "url",
                        "postedAt",
                        "text",
                        "mediaKind",
                        "likeCount",
                        "commentCount",
                        "viewCount",
                        "shareCount",
                        "saveCount",
                        "author"
                      ]
                    }
                  }
                },
                "required": [
                  "channels"
                ]
              }
            },
            "required": [
              "data"
            ],
            "description": "Returned with HTTP 200: the document we hold, wrapped the same way a batch read's `data` bucket wraps each entry."
          },
          "examples": {
            "somehandle": {
              "value": {
                "data": {
                  "channels": [
                    {
                      "network": "instagram",
                      "externalId": "17841400000000000",
                      "username": "somehandle",
                      "followersCount": 12345,
                      "verified": false,
                      "country": "US",
                      "instagram": {
                        "name": "Some Handle",
                        "biography": "Creator bio goes here.",
                        "website": "https://example.com",
                        "profilePictureUrl": "https://example.com/pic.jpg",
                        "followsCount": 200,
                        "mediaCount": 350,
                        "gender": "female",
                        "ageBucket": "25-34",
                        "onboardedStatus": true,
                        "portfolioUrl": "https://example.com/portfolio",
                        "email": "creator@example.com",
                        "isPaidPartnershipMessagesEnabled": true,
                        "hasBrandPartnershipExperience": true,
                        "pastBrandPartnershipPartners": [
                          "brand-a",
                          "brand-b"
                        ],
                        "badges": [
                          "top-creator"
                        ],
                        "reach": 8500,
                        "hasProfilePic": true,
                        "isPublished": true,
                        "creatorEngagedAccounts": 1362,
                        "reelsInteractionRate": 7.2,
                        "reelsHookRate": 42
                      },
                      "updatedAt": "2026-08-01T00:00:00.000Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "202": {
      "description": "We don't hold this entity yet — THIS request just started (or joined) the work to get it. Wait `Retry-After` seconds and re-read the same URL: the read is the poll, there is no job resource. A read here is not free of side effects — reading an entity we don't hold triggers discovery, and reading a stale one triggers a refresh.",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Delta-seconds (RFC 9110 §10.2.3), always ≥ 1. The server controls the backoff — polling faster than this burns rate limit and gets the data no sooner.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "fetching": {
                "minItems": 1,
                "maxItems": 1,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The identifier exactly as submitted."
                    },
                    "retryAfter": {
                      "type": "string",
                      "description": "ISO 8601 instant — every fetching entry in one response shares the same instant, and the response's Retry-After header (present iff this bucket is non-empty) is its delta-seconds twin."
                    }
                  },
                  "required": [
                    "id",
                    "retryAfter"
                  ],
                  "description": "A submitted identifier we don't hold yet — this batch read started (or joined) discovery for it. Re-submit it after Retry-After."
                }
              }
            },
            "required": [
              "fetching"
            ],
            "description": "Returned with HTTP 202: the entity isn't held yet and THIS request just started (or joined) the work to get it. Always exactly one entry (the identifier just submitted) — an array for shape-parity with the batch envelope's `fetching` bucket, not because a single read can return more than one. Wait Retry-After seconds, then re-read the same URL — the read is the poll; there is no job resource."
          }
        }
      }
    },
    "400": {
      "description": "A malformed request — e.g. a batch outside the 1–100 identifier cap, an unrecognized `include` value, `url` and `ids` supplied together, or an unparseable JSON body.",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The stable, machine-readable error code. Maps 1:1 to the HTTP status."
                  },
                  "message": {
                    "type": "string",
                    "description": "Human prose for logs and error screens. Never parse it."
                  },
                  "details": {
                    "description": "Optional structured extras. Today's one use: a read-miss 404's reason (and retryable, when our fault) — see `details.reason`.",
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "description": "Machine-readable, open vocabulary — same values a batch unavailable entry's own `reason` carries."
                      },
                      "retryable": {
                        "description": "Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "reason"
                    ]
                  }
                },
                "required": [
                  "code",
                  "message"
                ],
                "description": "The one JSON shape every error response (any status other than 200/202) carries, wrapped under `error` in `apiErrorResponseSchema`."
              }
            },
            "required": [
              "error"
            ],
            "description": "The one JSON shape every error response (any status other than 200/202) carries."
          },
          "example": {
            "error": {
              "code": "invalid-input",
              "message": "ids must contain between 1 and 100 identifiers, got 101"
            }
          }
        }
      }
    },
    "401": {
      "description": "Missing, malformed, expired, or revoked credential.",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The stable, machine-readable error code. Maps 1:1 to the HTTP status."
                  },
                  "message": {
                    "type": "string",
                    "description": "Human prose for logs and error screens. Never parse it."
                  },
                  "details": {
                    "description": "Optional structured extras. Today's one use: a read-miss 404's reason (and retryable, when our fault) — see `details.reason`.",
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "description": "Machine-readable, open vocabulary — same values a batch unavailable entry's own `reason` carries."
                      },
                      "retryable": {
                        "description": "Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "reason"
                    ]
                  }
                },
                "required": [
                  "code",
                  "message"
                ],
                "description": "The one JSON shape every error response (any status other than 200/202) carries, wrapped under `error` in `apiErrorResponseSchema`."
              }
            },
            "required": [
              "error"
            ],
            "description": "The one JSON shape every error response (any status other than 200/202) carries."
          },
          "example": {
            "error": {
              "code": "unauthorized",
              "message": "invalid credential"
            }
          }
        }
      }
    },
    "403": {
      "description": "Valid credential, but it lacks the `<resource>:<action>` permission this operation requires (stated in the operation description).",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The stable, machine-readable error code. Maps 1:1 to the HTTP status."
                  },
                  "message": {
                    "type": "string",
                    "description": "Human prose for logs and error screens. Never parse it."
                  },
                  "details": {
                    "description": "Optional structured extras. Today's one use: a read-miss 404's reason (and retryable, when our fault) — see `details.reason`.",
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "description": "Machine-readable, open vocabulary — same values a batch unavailable entry's own `reason` carries."
                      },
                      "retryable": {
                        "description": "Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "reason"
                    ]
                  }
                },
                "required": [
                  "code",
                  "message"
                ],
                "description": "The one JSON shape every error response (any status other than 200/202) carries, wrapped under `error` in `apiErrorResponseSchema`."
              }
            },
            "required": [
              "error"
            ],
            "description": "The one JSON shape every error response (any status other than 200/202) carries."
          },
          "example": {
            "error": {
              "code": "forbidden",
              "message": "token lacks creators:read permission"
            }
          }
        }
      }
    },
    "404": {
      "description": "A read-miss (branch on `details.reason` — retry only if `details.retryable` is `true`, never on `message` prose), an unknown `asProfile` (deliberately indistinguishable from a nonexistent one, so slugs are not enumerable), or an unsupported network. `details.reason` is an open vocabulary (additions are non-breaking). Values today: `account-not-discoverable` (creators — terminal; a personal account and a nonexistent handle are indistinguishable), `not-supported-on-network` (the network isn't supported yet — terminal until it ships), `outside-recent-media-window` (posts — terminal), `author-unresolved` (posts), `unparseable-identifier`, and `internal-error` with `details.retryable: true` (our fault — retry after a few minutes).",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The stable, machine-readable error code. Maps 1:1 to the HTTP status."
                  },
                  "message": {
                    "type": "string",
                    "description": "Human prose for logs and error screens. Never parse it."
                  },
                  "details": {
                    "description": "Optional structured extras. Today's one use: a read-miss 404's reason (and retryable, when our fault) — see `details.reason`.",
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "description": "Machine-readable, open vocabulary — same values a batch unavailable entry's own `reason` carries."
                      },
                      "retryable": {
                        "description": "Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "reason"
                    ]
                  }
                },
                "required": [
                  "code",
                  "message"
                ],
                "description": "The one JSON shape every error response (any status other than 200/202) carries, wrapped under `error` in `apiErrorResponseSchema`."
              }
            },
            "required": [
              "error"
            ],
            "description": "The one JSON shape every error response (any status other than 200/202) carries."
          },
          "example": {
            "error": {
              "code": "not-found",
              "message": "no creator found for instagram/somehandle",
              "details": {
                "reason": "account-not-discoverable"
              }
            }
          }
        }
      }
    },
    "429": {
      "description": "Over the per-principal request budget (fixed one-minute window; default 60 requests/minute, raisable per Service Account). Rejected requests still count against the window. Honour `Retry-After`.",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Delta-seconds (RFC 9110 §10.2.3), always ≥ 1. The server controls the backoff — polling faster than this burns rate limit and gets the data no sooner.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The stable, machine-readable error code. Maps 1:1 to the HTTP status."
                  },
                  "message": {
                    "type": "string",
                    "description": "Human prose for logs and error screens. Never parse it."
                  },
                  "details": {
                    "description": "Optional structured extras. Today's one use: a read-miss 404's reason (and retryable, when our fault) — see `details.reason`.",
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "description": "Machine-readable, open vocabulary — same values a batch unavailable entry's own `reason` carries."
                      },
                      "retryable": {
                        "description": "Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "reason"
                    ]
                  }
                },
                "required": [
                  "code",
                  "message"
                ],
                "description": "The one JSON shape every error response (any status other than 200/202) carries, wrapped under `error` in `apiErrorResponseSchema`."
              }
            },
            "required": [
              "error"
            ],
            "description": "The one JSON shape every error response (any status other than 200/202) carries."
          },
          "example": {
            "error": {
              "code": "rate-limited",
              "message": "rate limit exceeded (60 requests/minute for this principal)"
            }
          }
        }
      }
    },
    "500": {
      "description": "Our fault. The message is deliberately generic — internal error detail is never exposed. Safe to retry with backoff.",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The stable, machine-readable error code. Maps 1:1 to the HTTP status."
                  },
                  "message": {
                    "type": "string",
                    "description": "Human prose for logs and error screens. Never parse it."
                  },
                  "details": {
                    "description": "Optional structured extras. Today's one use: a read-miss 404's reason (and retryable, when our fault) — see `details.reason`.",
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "description": "Machine-readable, open vocabulary — same values a batch unavailable entry's own `reason` carries."
                      },
                      "retryable": {
                        "description": "Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "reason"
                    ]
                  }
                },
                "required": [
                  "code",
                  "message"
                ],
                "description": "The one JSON shape every error response (any status other than 200/202) carries, wrapped under `error` in `apiErrorResponseSchema`."
              }
            },
            "required": [
              "error"
            ],
            "description": "The one JSON shape every error response (any status other than 200/202) carries."
          },
          "example": {
            "error": {
              "code": "internal-error",
              "message": "the request could not be completed"
            }
          }
        }
      }
    },
    "503": {
      "description": "A dependency needed to verify the credential is unreachable — the credential was neither accepted nor rejected. Retry with backoff.",
      "headers": {
        "x-request-id": {
          "description": "On every response, success or failure. Quote it when contacting support — it's the fastest way for Aspire to find exactly your request.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The stable, machine-readable error code. Maps 1:1 to the HTTP status."
                  },
                  "message": {
                    "type": "string",
                    "description": "Human prose for logs and error screens. Never parse it."
                  },
                  "details": {
                    "description": "Optional structured extras. Today's one use: a read-miss 404's reason (and retryable, when our fault) — see `details.reason`.",
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "description": "Machine-readable, open vocabulary — same values a batch unavailable entry's own `reason` carries."
                      },
                      "retryable": {
                        "description": "Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "reason"
                    ]
                  }
                },
                "required": [
                  "code",
                  "message"
                ],
                "description": "The one JSON shape every error response (any status other than 200/202) carries, wrapped under `error` in `apiErrorResponseSchema`."
              }
            },
            "required": [
              "error"
            ],
            "description": "The one JSON shape every error response (any status other than 200/202) carries."
          },
          "example": {
            "error": {
              "code": "unavailable",
              "message": "temporarily unavailable"
            }
          }
        }
      }
    }
  }
}
```
