> ## Documentation Index
> Fetch the complete documentation index at: https://teardowns.aero/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> The two required headers and how Teardowns.aero verifies them.

Every call to `/public/v1/*` carries two headers. The API key
authenticates the caller, the organization id pins the request to a
specific org. Both are required on every request, missing either gets
a clean error before any business logic runs.

```http theme={null}
Authorization: Bearer tdao_live_<32 base32 characters>
X-Organization-Id: <organization-uuid>
```

## `Authorization`

The bearer token is the API key minted on **Settings → API Access**.

* Format: `tdao_live_` prefix + 32 base32 characters (lowercase),
  \~160 bits of entropy.
* Only the SHA-256 hash is stored, the raw value is never persisted.
  Lose it, revoke and re-mint.
* Carries no identity beyond "a key for org X minted by user Y." The
  user's capabilities are re-read on every request, so deactivating
  that user invalidates the key immediately.

<Frame caption="Settings → API Access. This is where the bearer token comes from. The raw value only ever appears once, at mint time.">
  <img src="https://mintcdn.com/teardownsaerollc/22_VxNBD6LkO537I/images/auth-01-api-access-page.png?fit=max&auto=format&n=22_VxNBD6LkO537I&q=85&s=078f91f79abae9cd32d4fed84d247db5" alt="Settings → API Access page with the keys table and a highlighted key row" width="1897" height="908" data-path="images/auth-01-api-access-page.png" />
</Frame>

## `X-Organization-Id`

The UUID of your organization. It's right above your keys table on
**Settings → API Access**, never changes, safe to hard-code in your
integration config.

Sending it explicitly (rather than relying on the key alone) gives us
two things: a belt-and-braces check that the key and header agree, and
a clean security signal a mismatch is **never** a legitimate user
error, so monitoring alerts on every occurrence.

<Frame caption="The Organization ID panel on Settings → API Access. Read-only, never changes, safe to put in plain config.">
  <img src="https://mintcdn.com/teardownsaerollc/22_VxNBD6LkO537I/images/auth-02-org-id-highlighted.png?fit=max&auto=format&n=22_VxNBD6LkO537I&q=85&s=14b961c72af09dc866fb51318f379b75" alt="Close-up of the Organization ID panel with the UUID highlighted and a Copy button" width="1882" height="907" data-path="images/auth-02-org-id-highlighted.png" />
</Frame>

## What we verify on each request

The request runs through these checks in order. Each step has its own
error code, so you can branch on exactly what went wrong, see
[errors](/concepts/errors) for the full list.

1. `Authorization` present and starts with `Bearer tdao_live_`.
2. `X-Organization-Id` is a parseable UUID.
3. `SHA-256(token)` matches a row in `api_keys`.
4. That row is `status='active'` and not past its expiry.
5. The key's `org_id` matches `X-Organization-Id`.
6. The org is in good standing (account status, subscription).
7. API access is enabled for that org.
8. The user who minted the key is still active in that org.
9. The user holds the capability the endpoint requires (writes need
   `seller`).

After all nine pass, the request runs the route's business logic.

Failure responses will look like:

```jsonc theme={null}
{
  "detail": {
    "error_code": "invalid_api_key",
    "message": "Invalid API key"
  }
}
```

Branch on `error_code` in code, show `message` to humans.

## Common questions

<AccordionGroup>
  <Accordion title="Can I share one API key across multiple ERPs?">
    Technically yes but you lose the ability to rotate / revoke per
    integration. Mint one key per integration so when one needs to be
    rotated the others are unaffected.
  </Accordion>

  <Accordion title="What happens if the user who minted the key leaves the org?">
    The key starts returning 403 `api_key_creator_revoked` immediately
    (we re-check the creator on every request). A background sweep also
    flips the key to revoked within an hour so subsequent calls return
    401\. Have another eligible member mint a replacement key before
    offboarding the original minter.
  </Accordion>

  <Accordion title="Does rotating a key invalidate old requests?">
    Rotation is atomic the old key returns 401 the instant the new key
    appears. Requests already past the lookup step with the old key
    complete normally. The window is tiny and benign.
  </Accordion>

  <Accordion title="Is HTTPS required?">
    Yes. Production accepts HTTPS only. The API key in plaintext over
    HTTP is a leak.
  </Accordion>
</AccordionGroup>
