{"openapi":"3.0.3","info":{"title":"Zaptrain API","version":"1.0.0","description":"REST API for Zaptrain — manage your merchant profile and invoices programmatically. API keys are managed from the Settings page."},"servers":[{"url":"/","description":"Current server"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key generated from the Settings page. Format: `Authorization: Bearer isvk_<key>`"},"cookieAuth":{"type":"apiKey","in":"cookie","name":"sb-access-token","description":"Session cookie set after signing in via the web interface."}},"schemas":{"Merchant":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"},"name":{"type":"string","example":"Acme Corp"},"email":{"type":"string","format":"email","example":"hello@acme.com"},"brand_name":{"type":"string","nullable":true,"example":"Acme"},"brand_color":{"type":"string","nullable":true,"example":"#3B82F6"},"logo_url":{"type":"string","nullable":true,"example":"/api/logo/logo-abc123.png"},"default_memo":{"type":"string","nullable":true,"example":"Thank you for your business!"},"created_at":{"type":"string","format":"date-time","example":"2024-01-15T10:30:00Z"}}},"MerchantUpdate":{"type":"object","properties":{"brand_name":{"type":"string","nullable":true,"example":"Acme"},"brand_color":{"type":"string","nullable":true,"example":"#3B82F6"},"default_memo":{"type":"string","nullable":true,"example":"Thank you for your business!"}}},"Usage":{"type":"object","properties":{"fee_rate":{"type":"number","example":0.01},"fee_rate_pct":{"type":"string","example":"1%"},"description":{"type":"string","example":"1% of each transaction amount"}}},"Invoice":{"type":"object","properties":{"id":{"type":"integer","example":42},"public_id":{"type":"string","example":"xK9mPqR3vN7w"},"merchant_id":{"type":"string","format":"uuid"},"customer_name":{"type":"string","nullable":true,"example":"Jane Smith"},"customer_email":{"type":"string","format":"email","nullable":true,"example":"jane@example.com"},"status":{"type":"string","enum":["draft","sent","paid","cancelled"],"example":"sent"},"currency":{"type":"string","example":"SATS"},"amount_cents":{"type":"integer","description":"Total amount in satoshis","example":50000},"memo":{"type":"string","nullable":true,"example":"Web design services — March 2024"},"due_date":{"type":"string","nullable":true,"example":"2024-04-01"},"bolt11":{"type":"string","nullable":true,"description":"Lightning Network BOLT11 payment request"},"tax_percent":{"type":"number","nullable":true,"example":10},"tax_amount_sats":{"type":"integer","nullable":true,"example":5000},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"InvoiceList":{"type":"object","properties":{"invoices":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"total":{"type":"integer","example":23}}},"Error":{"type":"object","properties":{"error":{"type":"string","example":"Unauthorized"}}}},"responses":{"Unauthorized":{"description":"Not authenticated — provide a valid API key or session cookie","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Unauthorized"}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Not found"}}}}}},"security":[{"bearerAuth":[]},{"cookieAuth":[]}],"paths":{"/api/v1/users/me":{"get":{"summary":"Get current merchant profile","operationId":"getMerchant","tags":["Users"],"responses":{"200":{"description":"Merchant profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Merchant"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"patch":{"summary":"Update merchant profile","operationId":"updateMerchant","tags":["Users"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantUpdate"}}}},"responses":{"200":{"description":"Updated merchant profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Merchant"}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/users/me/usage":{"get":{"summary":"Get fee rate information","operationId":"getMerchantUsage","tags":["Users"],"responses":{"200":{"description":"Flat-fee rate information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/invoices":{"get":{"summary":"List invoices","operationId":"listInvoices","tags":["Invoices"],"parameters":[{"name":"limit","in":"query","description":"Max number of invoices to return (default 20, max 100)","schema":{"type":"integer","default":20,"minimum":1,"maximum":100}},{"name":"offset","in":"query","description":"Number of invoices to skip for pagination","schema":{"type":"integer","default":0,"minimum":0}}],"responses":{"200":{"description":"Paginated invoice list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/invoices/{id}":{"get":{"summary":"Get a single invoice","operationId":"getInvoice","tags":["Invoices"],"parameters":[{"name":"id","in":"path","required":true,"description":"Invoice ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Invoice detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/invoices/{id}/cancel":{"post":{"summary":"Cancel an invoice","description":"Soft-cancel an outstanding invoice. Preserves the invoice row and history. Paid invoices cannot be cancelled, and drafts must be deleted instead. Idempotent on already-cancelled invoices.","operationId":"cancelInvoice","tags":["Invoices"],"parameters":[{"name":"id","in":"path","required":true,"description":"Invoice ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Invoice cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"status":{"type":"string","example":"cancelled"},"invoice":{"$ref":"#/components/schemas/Invoice"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Invoice cannot be cancelled in its current state (paid invoices cannot be cancelled; drafts must be deleted instead).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"paid":{"value":{"error":"Cannot cancel a paid invoice"}},"draft":{"value":{"error":"Drafts cannot be cancelled; delete them instead"}}}}}}}}}},"tags":[{"name":"Users","description":"Merchant profile and usage operations"},{"name":"Invoices","description":"Invoice read operations"}]}