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

# API Access Model

> Internal TattooAPI access, projection, and write-authority model for the current waves.

# API Access Model

TattooAPI does not treat a noun as simply public or private.

The working rule is:

* one noun can have multiple projections
* reads and writes are actor-scoped
* canonical truth authority stays internal-first

## Projection Types

* `public_projection`
  * publish-state-aware, redacted, rights-cleared read surface
* `owner_projection`
  * authenticated owner view and future owner-scoped write surface for approved fields only
* `participant_projection`
  * restricted read view for parties in a booking, session, quote, or transaction
* `operator_projection`
  * internal governance, trust, proof, ranking, legal, compliance, and workflow lineage view

## Current Default

* public reads stay narrow
* public writes stay blocked
* approved credentials are the default auth path for internal beta, owner, operator, and private worker calls
* TattooAPI maps verified identities to actors and owner scopes
* owner-scoped writes are defined for future use but are not broadly activated
* public intake may exist later, but it is never direct mutation authority
* internal runtime routes remain the only promoted mutation surface

## WorkOS Machine-to-Machine Boundary

TattooAPI's current machine-to-machine path uses WorkOS organization API keys sent to TattooAPI through `X-API-Key`. This is API-key-based M2M authentication, not an OAuth client-credentials flow.

```text theme={"dark"}
Private service
  -> X-API-Key
  -> WorkOS validates the organization API key
  -> TattooAPI resolves the non-secret WorkOS key ID
  -> Convex returns the TattooAPI service-actor mapping
  -> TattooAPI enforces mapped permissions and tenant scopes
  -> governed route or explicit denial
```

The two layers have different jobs:

| Layer              | Owns                                                                                                                                         | Does not own                               |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| WorkOS             | Key creation, one-time secret delivery, organization ownership, permission metadata, validation, rotation, and revocation                    | TattooAPI tenant policy or write authority |
| TattooAPI + Convex | Actor type, organization, studio and artist scopes, internal service capabilities, route authorization, review separation, and audit lineage | API key secret values                      |

A valid WorkOS key is not sufficient by itself. If its non-secret key ID has no active TattooAPI actor mapping, TattooAPI returns `403`.

### Current Permanent service boundary

The Production Permanent machine key is intentionally narrow:

* WorkOS key permissions: `artists:read` and `portfolio_intake:stage`
* TattooAPI actor: approved service mapping with the required organization and intake scope
* internal mapping capability: `portfolio_intake:stage_cross_tenant` for governed identity resolution and staging across approved tenants
* denied authority: portfolio approval, Sanity promotion, canonical runtime promotion, and public publication

`portfolio_intake:stage_cross_tenant` is a TattooAPI service-actor capability. It is not a self-service WorkOS key permission and does not bypass the separate human review boundary.

## Current Route Families

Promoted public reads:

* `GET /api/v1/health/live`
* `GET /api/v1/health/ready`
* `GET /api/v1/studios`

Public compatibility ingress, not promoted public product surface:

* `/api/v1/docs`
* `/api/v1/search/autocomplete`
* `/api/v1/auth/*` legacy compatibility routes
* `/api/v1/webhooks/stripe`

Authenticated discovery beta:

* `GET /api/v1/search`

Internal authenticated read beta:

* `GET /api/v1/artists`
* `GET /api/v1/artists/[id]`
* `GET /api/v1/portfolios`
* `GET /api/v1/portfolios/[id]`
* `GET /api/v1/designs`
* `GET /api/v1/designs/[id]`

Creative route contract hardening:

* `/api/v1/portfolios*` and `/api/v1/designs*` now return only `public_projection`
* they require `publish_state = published_public`
* `POST`, `PUT`, `PATCH`, and `DELETE` are explicitly blocked

Owner-scoped private beta reads:

* `GET /api/v1/me/portfolio-assets`
* `GET /api/v1/me/portfolio-assets/[id]`
* `GET /api/v1/me/designs`
* `GET /api/v1/me/designs/[id]`

Owner route contract hardening:

* authenticated and owner-filtered
* can read `draft`, `owner_private`, and `published_public`
* mutations stay gated until explicit owner write contracts land

Retired local API-key management:

* `/api/v1/api-keys*` returns `410`
* machine credentials are created and revoked in the partner portal
* TattooAPI stores only non-secret credential identity metadata and actor mappings

Known mixed posture:

* booking routes still carry runtime-read plus legacy-write compatibility and are not a template for new public mutation work
* duplicate brand detail route files exist in the implementation and should be cleaned up before brand docs are promoted

Internal operator writes:

* `POST /api/internal/runtime/workflow-transition`
* `POST /api/internal/runtime/review-queue`
* `POST /api/internal/runtime/recertification`
* `POST /api/internal/runtime/lane-refresh`

Reference pages:

* [List Portfolios](/api-reference/creative/portfolios)
* [List Designs](/api-reference/creative/designs)
* [My Portfolio Assets](/api-reference/creative/owner-portfolio-assets)
* [My Designs](/api-reference/creative/owner-designs)

## Noun Guidance

`Studio` and `ArtistProfile`:

* public read summaries are acceptable
* future owner-scoped writes should land on explicit owner route families
* ranking, compliance, review lineage, and operator notes stay internal

`PortfolioAsset` and `Design`:

* only published, rights-cleared records should be public
* artists or owning studios may later patch approved self-owned fields
* drafts, unpublished assets, raw vision metadata, proof checks, and rights disputes stay internal

`Booking`, `JobSession`, `EstimateQuote`, `PaymentArrangement`, and transaction/provider posture:

* these are participant-scoped, not broad public reads
* readiness and provider mapping remain internal-first

`TrustEvidence`, `PortfolioProofCheck`, `PortfolioProofVerdict`, `PolicyDecision`, law, and compliance:

* internal only, with future redacted summaries at most

## Cross-Studio Privacy

Another studio should not automatically see another studio's:

* draft or unpublished portfolio assets
* private design metadata
* raw model observations
* pricing history
* proof disputes or operator notes
* client, booking, or payout details

Cross-studio visibility should be limited to intentionally public projections and future governed partner envelopes.

## Wave F+ Gate

The next public expansion is not "make everything public." It is a gated public-read program.

Before a new public read, SDK surface, public page, or free tool becomes active, it needs:

* TattooAPI runtime truth for the subject family
* reviewed source lineage
* rights and consent posture
* publish-state or redaction rules
* owner and cross-studio privacy checks
* operator rollback and audit path

See [Future Wave Gates](/guides/future-wave-gates) for the current F+ gate model.

## Future Route Pattern

When subject-scoped writes are turned on later, they should use explicit route families such as:

* `/api/v1/me/*`
* `/api/v1/intake/*`
* `/api/internal/runtime/*`

That split keeps:

* public reads narrow
* owner writes explicit
* participant visibility restricted
* canonical truth authority internal-first

The deeper internal source of truth is [Project Status](/project-status) plus the control-plane doc `project-context/ontology/api-access-and-privacy-matrix.md` in the repo.
