# REST API (/v1)

Same lifecycle as MCP, built for platforms at volume. Full contract: [OpenAPI](https://themassprint.com/openapi.json).

## Auth

`Authorization: Bearer mp_live_...` — issued manually (contact work@msomu.com).
Keys carry a **payment mode**:
- `payment_link` (default): each order returns a Razorpay link your buyer pays.
- `invoiced` (enterprise partners): orders auto-confirm with **no payment link**, are priced at a
  platform discount off retail (default −25%), and are settled monthly against a statement of
  confirmed orders. Keep your own checkout; we never touch your buyer.

### Getting an enterprise (invoiced) key

Self-serve, GSTIN required for tax invoicing. Keys are reviewed before issue — once approved, the key
is emailed to your contact address. Two ways to apply:

- **Agents:** call the `apply_enterprise` MCP tool.
- **REST/web:** `POST /v1/enterprise/apply` (no auth):
  ```json
  { "company_name": "...", "contact_email": "...", "gstin": "29ABCDE1234F1Z5", "expected_monthly_volume": 200 }
  ```

Until a key is approved, print immediately with the normal payment-link flow.

Anonymous (keyless) ordering works like MCP: order access via `order_token`.
Uploads are the exception — they write to our print storage, so `POST /v1/uploads`
needs an API key or a signed-in web session. Keyless agents upload via MCP `create_upload`.

## Endpoints

```
POST   /v1/uploads                    → { upload_id, put_url, expires_at, max_bytes }   auth required
PUT    <put_url>                      → { upload_id, validation }          (signed URL, no bearer)
GET    /v1/uploads/:id/validation     → { upload_id, validation }          auth required, own uploads only
POST   /v1/orders                     → { order, order_token }             201
GET    /v1/orders/:id                 → { order }        auth: key that created it, or ?token=<order_token>
POST   /v1/orders/:id/cancel          → { order_id, status }               only awaiting_payment
GET    /v1/catalog                    → catalog + prices
POST   /v1/webhook-endpoints          → { id, url, secret }                register status callbacks
GET    /v1/webhook-endpoints          → list
DELETE /v1/webhook-endpoints/:id      → deactivate
GET    /v1/health                     → { ok: true }
```

`POST /v1/orders` body is identical to MCP `create_order` arguments.

## Order statuses

`awaiting_payment → confirmed → printing → shipped → delivered`, with `expired` (72 h unpaid), `canceled`, `refunded`. Ship SLA: 5 business days from confirmation (manual fulfilment, V1).
