Invoices API
REST endpoints for issuing, tracking, and paying Studio invoices. All paths are relative to the Studio base URL. Provider operations require a ysk_prov_* bearer token; client operations accept an org member session token. Authorization is enforced by SpiceDB: providers may only touch invoices for organizations they are assigned to, and members may only read/pay their own org's invoices.
Endpoints
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /api/studio/invoices | either | List (filter org/project/status) |
| POST | /api/studio/invoices | provider | Create DRAFT |
| GET | /api/studio/invoices/summary | either | Aggregate for one org |
| GET | /api/studio/invoices/:id | either | Detail |
| PATCH | /api/studio/invoices/:id | provider | Update DRAFT |
| POST | /api/studio/invoices/:id/send | provider | Finalize + Stripe send |
| POST | /api/studio/invoices/:id/cancel | provider | Void |
| GET | /api/studio/invoices/:id/pay-link | client | Stripe hosted URL |
Create
POST /api/studio/invoices
Authorization: Bearer ysk_prov_capswan-studio
Content-Type: application/json
{
"organizationId": "org_acme",
"description": "March retainer",
"lineItems": [
{ "description": "Design sprint", "quantity": 1, "unitPriceCents": 500000 },
{ "description": "Frontend dev", "quantity": 40, "unitPriceCents": 15000 }
],
"dueDate": "2026-04-15"
}
→ 201 Created
{
"id": "inv_01H...",
"number": "STUDIO-2026-0042",
"status": "DRAFT",
"amountCents": 1100000, // computed server-side
"lineItems": [ ... totalCents filled in ... ],
...
} Pay link
GET /api/studio/invoices/inv_01H.../pay-link
Authorization: Bearer <member-session-token>
→ 200 OK
{ "hostedInvoiceUrl": "https://invoice.stripe.com/i/acct_.../live_..." } The portal opens this URL directly. Card data is handled entirely by Stripe; the Studio API and the provider portal are out of PCI scope.
Errors
Errors use the standard Studio envelope. The SDK throws StudioApiError with status, message, and optional code.
| Status | When |
|---|---|
| 403 | Provider not assigned to org / member not in org |
| 409 | Editing/sending a non-DRAFT, cancelling a PAID invoice |
| 422 | Empty line items or non-positive quantity/price |