| Request | Who may call | Success |
|---------|--------------|---------|
| GET /api/licenses | licenses:read | 200, a list. ?search= filters it |
| POST /api/licenses | licenses:write | 201, a license |
| DELETE /api/licenses/{license} | licenses:write | 202, queued |
| POST /api/license-batches | licenses:write | 202, a batch ID |
| GET /api/license-batches/{id} | licenses:write, its owner | 200, progress |
| POST /api/exports | licenses:read | 202, an export ID |
| GET /api/exports/{id} | licenses:read, its owner | 302, a link that expires |
| GET /api/consumers | operators | 200, paginated |
| POST /api/consumers | operators | 201, a consumer |
| GET /api/consumers/{consumer} | operators, or itself | 200 |
| PATCH /api/consumers/{consumer} | operators | 200. Sets limits and the webhook |
| DELETE /api/consumers/{consumer} | operators | 204 |
| GET /api/consumers/{consumer}/tokens | operators | 200, no secrets |
| POST /api/consumers/{consumer}/tokens | operators | 201, the token, once |
| DELETE .../tokens/{token} | operators | 204 |
| GET /up | anyone | 200 when the instance can serve |
An operator is a caller whose token has the consumers:manage ability.
Request Headers
| Header | Purpose | Chapter |
|--------|---------|---------|
| Authorization: Bearer ... | Identifies the consumer | 4 |
| Accept-Language | Language of messages | 6 |
| X-Trace-Id | A UUID carried through logs and jobs | 7 |
| Idempotency-Key | A UUID that makes a POST safe to retry | 8 |
| Api-Version | Response shape | 16 |
Responses When Something Is Wrong
| Status | code | Meaning |
|--------|--------|---------|
| 400 | | The Idempotency-Key is not a UUID |
| 401 | | No valid token |
| 403 | | The token may not do this |
| 404 | | Not found, or not yours to see |
| 409 | request_in_progress | The same request is still running |
| 409 | license_limit_reached | The consumer is at its limit |
| 422 | | Validation failed. See errors, by field. Without errors, an idempotency key was reused |
| 429 | | Rate limit reached. See Retry-After |
| 502 | provider_failed | The provider had an error. Retry |
| 502 | provider_rejected | The provider refused. Don’t retry |
| 504 | provider_unavailable | The provider did not answer. Retry |
| 500 | | A fault in this API |
Every one of them has a message.
Where Things Live
| Concern | File |
|---------|------|
| Routes | routes/api.php |
| Middleware, exceptions | bootstrap/app.php |
| HTTP in and out | app/Http/Controllers |
| The request pipeline | app/Http/Middleware |
| Validation | app/Http/Requests |
| Output shape | app/Http/Resources |
| Provider integration and typed data | app/Services/License |
| The name the application calls it by | app/Facades |
| Abilities, error codes, versions | app/Enums |
| Validation rules of your own | app/Rules |
| Authorization on records | app/Policies |
| Data you own | app/Models |
| Failures with a name | app/Exceptions |
| Background work | app/Jobs, app/Listeners |
| Work started from a terminal | app/Console/Commands |
| Rate limiter, health checks | app/Providers/AppServiceProvider.php |
| Schedules | routes/console.php |
| Retention windows, version dates | config/retention.php, config/api.php |