REF-701-01: API Response Contract
ADR: ADR-701 — API & AuthenticationEscopo: Estrutura JSON do envelope, campos meta, 7 error codes, exemplos, headers obrigatórios, paginação
1. Envelope de Resposta
Todos os endpoints retornam:
{
"success": true,
"data": { },
"meta": {
"page": 1,
"per_page": 20,
"total": 100,
"pages": 5
},
"message": null,
"errors": null
}| Campo | Tipo | Sempre presente | Descrição |
|---|---|---|---|
success | boolean | Sim | true para 2xx, false para erros |
data | object / array | Sim | Payload (null em erros) |
meta | object / null | Sim | Paginação (null se N/A) |
message | string / null | Sim | Mensagem humanizada (null se N/A) |
errors | object / null | Sim | Detalhes de erro (null em sucesso) |
2. Campos Meta (Paginação)
Presente em endpoints de lista:
| Campo | Tipo | Descrição |
|---|---|---|
page | int | Página atual |
per_page | int | Itens por página |
total | int | Total de itens |
pages | int | Total de páginas |
Query params: ?page=1&per_page=20 (defaults).
3. 7 Error Codes
| Code | HTTP | Quando | Exemplo errors |
|---|---|---|---|
VALIDATION_ERROR | 422 | Input inválido | {"fields": {"email": ["Email is required"]}} |
AUTHENTICATION_ERROR | 401 | Sem token, expirado, inválido | {"code": "AUTHENTICATION_ERROR", "detail": "Token expired"} |
AUTHORIZATION_ERROR | 403 | Sem permissão | {"code": "AUTHORIZATION_ERROR", "detail": "Scope 'finances' required"} |
NOT_FOUND | 404 | Recurso não existe | {"code": "NOT_FOUND", "detail": "Organization 42 not found"} |
CONFLICT | 409 | Estado conflitante | {"code": "CONFLICT", "detail": "Entitlement already cancelled"} |
RATE_LIMIT | 429 | Excedeu limite | {"code": "RATE_LIMIT", "detail": "5 requests/min exceeded"} |
INTERNAL_ERROR | 500 | Erro interno | {"code": "INTERNAL_ERROR", "detail": "Unexpected error"} |
4. Exemplos
Sucesso (item único)
{
"success": true,
"data": {
"id": 42,
"name": "Acme Corp",
"tax_id": "XX.XXX.XXX/XXXX-XX",
"status": "verified"
},
"meta": null,
"message": null,
"errors": null
}Sucesso (lista paginada)
{
"success": true,
"data": [
{ "id": 1, "code": "PLG-2026040001" },
{ "id": 2, "code": "ENV-2026040002" }
],
"meta": { "page": 1, "per_page": 20, "total": 2, "pages": 1 },
"message": null,
"errors": null
}Erro (validação)
{
"success": false,
"data": null,
"meta": null,
"message": "Validation failed",
"errors": {
"code": "VALIDATION_ERROR",
"fields": {
"email": ["Email is required"],
"name": ["Name must be at least 2 characters"]
}
}
}5. Headers Obrigatórios
| Header | Direção | Obrigatório | Valor |
|---|---|---|---|
Authorization | Request | Sim * | Bearer {jwt_token} |
X-Middag-Organization | Request | Sim ** | ID da organization |
X-Middag-Company | Request | Não | middag_br / middag_global |
Content-Type | Request | Sim (POST/PUT) | application/json |
Content-Type | Response | Sempre | application/json |
* Exceto /auth/login e endpoints públicos ** Exceto endpoints que não operam sobre dados de organization
6. HTTP Status Codes
| Code | Meaning | Context |
|---|---|---|
| 200 | OK | Successful request |
| 201 | Created | Resource created successfully |
| 400 | Bad Request | Invalid or missing parameters |
| 401 | Unauthorized | Token absent, invalid, or expired |
| 403 | Forbidden | No permission for resource/action |
| 404 | Not Found | Resource not found |
| 409 | Conflict | State conflict (e.g., email already exists) |
| 422 | Unprocessable Entity | Business validation failed |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Internal server error |
7. Pagination Parameters
List endpoints accept:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | int | 1 | Current page |
per_page | int | 20 | Items per page (max: 100) |
order | string | desc | Direction: asc or desc |
orderby | string | created_at | Sort field |
search | string | — | Text search (when supported) |
8. Authentication Types
| Type | Description | Used by |
|---|---|---|
| JWT RS256 Bearer | JWT signed with RS256 in Authorization: Bearer {token} header | Most protected endpoints |
| Refresh Token | Opaque token used exclusively to renew expired JWT | /auth/refresh |
| Stripe Signature | Validation via Stripe-Signature header with webhook secret | Stripe webhooks |
| HubSpot Signature | Validation via X-HubSpot-Signature header with client secret | HubSpot webhooks |
| Invite Token | Unique token sent by email for invite operations | Collaborator invite endpoints |
| Public | No authentication | Register, login, password reset |
9. Endpoint Catalog
Base URL: https://account.middag.com.br/wp-json/middag-account/v1
9.1 Auth Endpoints (/auth/*)
| # | Method | Endpoint | Auth | Description |
|---|---|---|---|---|
| 1 | POST | /auth/login | Public | Login with email/password, returns JWT |
| 2 | POST | /auth/register | Public | Full registration with all fields |
| 3 | POST | /auth/register-email | Public | Email-only registration (OAuth flow) |
| 4 | POST | /auth/refresh | Refresh Token | Renew JWT using refresh token |
| 5 | GET | /auth/user | JWT | Authenticated user data |
| 6 | POST | /auth/update-profile | JWT | Update profile data |
| 7 | POST | /auth/forgot-password | Public | Request password reset token |
| 8 | POST | /auth/validate-reset-token | Public | Validate reset token validity |
| 9 | POST | /auth/reset-password | Public | Reset password with valid token |
| 10 | POST | /auth/check-user | Public | Check if email is already registered |
| 11 | POST | /auth/resend-verification | Public | Resend account verification email |
| 12 | POST | /auth/verify-account | Public | Verify account using email token |
POST /auth/login — Request/Response:
// Request
{
"email": "user@example.com",
"password": "securePassword123"
}
// Response (200)
{
"success": true,
"data": {
"user": {
"id": 123,
"email": "user@example.com",
"display_name": "User Name",
"roles": [
"subscriber"
],
"email_verified": true
},
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"refresh_token": "rt_abc123def456...",
"expires_in": 86400
}
}POST /auth/refresh — Request/Response:
// Request
{
"refresh_token": "rt_abc123def456..."
}
// Response (200)
{
"success": true,
"data": {
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"refresh_token": "rt_newtoken789...",
"expires_in": 86400
}
}Rate limits: /auth/login 5/min/IP, /auth/register 3/min/IP, /auth/forgot-password 3/5min/IP.
9.2 Organization Endpoints (/organizations/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 13 | GET | /organizations | JWT | — | List user's organizations |
| 14 | POST | /organizations | JWT | — | Create new organization |
| 15 | GET | /organizations/{id} | JWT + Org | organization | Organization details |
| 16 | PUT | /organizations/{id} | JWT + Org | organization | Update organization data |
| 17 | DELETE | /organizations/{id} | JWT + Org | organization (owner) | Delete organization |
| 18 | POST | /organizations/cnpj-check | JWT | — | Validate CNPJ with federal API |
| 19 | GET | /organizations/{id}/collaborators | JWT + Org | organization | List organization members |
9.3 Collaborator Endpoints (/collaborators/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 20 | POST | /collaborators | JWT + Org | organization | Invite new collaborator |
| 21 | GET | /collaborators/{id} | JWT + Org | organization | Collaborator details |
| 22 | PUT | /collaborators/{id} | JWT + Org | organization | Update role/permissions |
| 23 | DELETE | /collaborators/{id} | JWT + Org | organization | Remove collaborator |
| 24 | POST | /collaborators/check-invite | Token | — | Verify invite validity |
| 25 | POST | /collaborators/accept-invite | Token | — | Accept invite |
| 26 | POST | /collaborators/reject-invite | Token | — | Reject invite |
| 27 | POST | /collaborators/{id}/resend-invite | JWT + Org | organization | Resend invite email |
Roles: owner (full access), admin (manage members), member (scoped access), guest (restricted read), pending (invite not accepted).
Scopes: organization, orders, finances, quotes, contracts, documents, licenses, downloads, entitlements, admin.
9.4 Order Endpoints (/orders/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 28 | GET | /orders | JWT + Org | orders | List organization orders |
| 29 | GET | /orders/{id} | JWT + Org | orders | Full order details |
| 30 | POST | /orders/{id}/cancel | JWT + Org | orders | Cancel pending order |
| 31 | POST | /orders/{id}/refund | JWT + Org | orders + finances | Request refund |
Query filters: status (pending/processing/completed/cancelled/refunded), date_from, date_to.
9.5 Invoice Endpoints (/invoices/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 32 | GET | /invoices | JWT + Org | finances | List invoices |
| 33 | GET | /invoices/{id} | JWT + Org | finances | Invoice details |
| 34 | GET | /invoices/{id}/pdf | JWT + Org | finances | Download invoice PDF |
| 35 | GET | /invoices/order/{order_id} | JWT + Org | finances | Invoices linked to an order |
9.6 Tax Invoice Endpoints (/tax-invoices/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 36 | GET | /tax-invoices | JWT + Org | finances | List NFSe |
| 37 | GET | /tax-invoices/{id} | JWT + Org | finances | NFSe details |
| 38 | GET | /tax-invoices/{id}/pdf | JWT + Org | finances | Download NFSe PDF |
| 39 | GET | /tax-invoices/order/{order_id} | JWT + Org | finances | NFSe linked to an order |
9.7 Quote Endpoints (/quotes/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 40 | GET | /quotes | JWT + Org | quotes | List quotes |
| 41 | GET | /quotes/{id} | JWT + Org | quotes | Quote details |
| 42 | POST | /quotes/{id}/accept | JWT + Org | quotes | Accept quote |
| 43 | POST | /quotes/{id}/reject | JWT + Org | quotes | Reject quote |
| 44 | GET | /quotes/{id}/payment | JWT + Org | quotes + finances | Payment status |
Query filters: status (draft/sent/accepted/rejected/expired).
9.8 Contract Endpoints (/contracts/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 45 | GET | /contracts | JWT + Org | contracts | List contracts |
| 46 | GET | /contracts/{id} | JWT + Org | contracts | Contract details |
| 47 | GET | /contracts/{id}/pdf | JWT + Org | contracts | Download contract PDF |
9.9 Document Endpoints (/documents/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 48 | GET | /documents | JWT + Org | documents | List documents |
| 49 | GET | /documents/{id} | JWT + Org | documents | Document details |
| 50 | GET | /documents/{id}/download | JWT + Org | documents | Download file |
9.10 License Endpoints (/licenses/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 51 | GET | /licenses | JWT + Org | licenses | List licenses |
| 52 | GET | /licenses/{id} | JWT + Org | licenses | License details |
| 53 | POST | /licenses/{id}/activate | JWT + Org | licenses | Activate license on domain |
| 54 | POST | /licenses/{id}/deactivate | JWT + Org | licenses | Deactivate from domain |
9.11 Download Endpoints (/downloads/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 55 | GET | /downloads | JWT + Org | downloads | List available downloads |
| 56 | GET | /downloads/{id} | JWT + Org | downloads | Get signed download URL |
9.12 Entitlement Endpoints (/entitlements/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 57 | GET | /entitlements | JWT + Org | entitlements | List organization entitlements |
| 58 | GET | /entitlements/{id} | JWT + Org | entitlements | Entitlement details |
| 59 | GET | /entitlements/code/{code} | JWT + Org | entitlements | Lookup by code (e.g., PLG-2026040142) |
| 60 | GET | /entitlements/{id}/orders | JWT + Org | entitlements | Linked orders |
| 61 | GET | /entitlements/{id}/licenses | JWT + Org | entitlements | Linked licenses |
| 62 | GET | /entitlements/{id}/contracts | JWT + Org | entitlements | Linked contracts |
Query filters: class (PLG/ENV/SVC/ORD/AFL/EDU), status (active/suspended/expired/cancelled).
9.13 Environment Endpoints (/environments/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 63 | GET | /environments | JWT + Org | entitlements | List managed environments |
| 64 | GET | /environments/{id} | JWT + Org | entitlements | Environment details |
| 65 | GET | /environments/{id}/service-requests | JWT + Org | entitlements | Service requests linked to env |
| 66 | POST | /environments/{id}/service-requests | JWT + Org | entitlements | Create service request for env |
Query filters: status (provisioning/active/maintenance/suspended/decommissioned), platform (moodle/wordpress/custom), environment_type (production/staging/development/sandbox).
9.14 Service Endpoints (/services/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 67 | GET | /services | JWT + Org | entitlements | List organization services |
| 68 | GET | /services/{id} | JWT + Org | entitlements | Service details |
| 69 | GET | /services/{id}/service-requests | JWT + Org | entitlements | Service requests for service |
Query filters: status (proposal/approved/in_progress/on_hold/delivered/closed/cancelled), lifecycle (ongoing/project) + type (a definir).
9.15 ServiceRequest Endpoints (/service-requests/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 70 | GET | /service-requests | JWT + Org | entitlements | List organization SRs |
| 71 | GET | /service-requests/{id} | JWT + Org | entitlements | SR details |
| 72 | POST | /service-requests | JWT + Org | entitlements | Create service request |
| 73 | GET | /service-requests/{id}/history | JWT + Org | entitlements | Status transition history |
Number format: SR-{YEAR}{SEQ:4d}. Clients can only create SRs for ENV-class entitlements (standalone). Admin can create for any entitlement/service.
9.16 Affiliate Endpoints (/affiliates/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 74 | GET | /affiliates/me | JWT | — | Logged-in affiliate data |
| 75 | POST | /affiliates/register | JWT | — | Register as affiliate |
9.17 Admin Endpoints (/admin/*)
| # | Method | Endpoint | Auth | Scope | Description |
|---|---|---|---|---|---|
| 76 | GET | /admin/users | JWT (admin) | admin | List all users |
| 77 | GET | /admin/organizations | JWT (admin) | admin | List all organizations |
9.18 Webhook Endpoints (/webhooks/*)
No JWT auth — validated by service-specific signatures.
| # | Method | Endpoint | Auth | Description |
|---|---|---|---|---|
| 78 | POST | /webhooks/stripe | Stripe Signature | Stripe events (company via header) |
| 79 | POST | /webhooks/hubspot | HubSpot Signature | HubSpot events (company via header) |
Stripe events processed: checkout.session.completed, invoice.paid, invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted, charge.refunded.
HubSpot events processed: Contact create/update, deal stage changes, form submissions.
Company routing uses X-Middag-Company header (unified endpoint, not split by path).
10. Summary and Counts
By Group
| Group | Endpoints | Methods |
|---|---|---|
| Auth | 12 | 2 GET, 10 POST |
| Organizations | 7 | 3 GET, 2 POST, 1 PUT, 1 DELETE |
| Collaborators | 8 | 1 GET, 6 POST, 1 PUT, 1 DELETE |
| Orders | 4 | 2 GET, 2 POST |
| Invoices | 4 | 4 GET |
| Tax Invoices | 4 | 4 GET |
| Quotes | 5 | 3 GET, 2 POST |
| Contracts | 3 | 3 GET |
| Documents | 3 | 3 GET |
| Licenses | 4 | 2 GET, 2 POST |
| Downloads | 2 | 2 GET |
| Entitlements | 6 | 6 GET |
| Environments | 4 | 3 GET, 1 POST |
| Services | 3 | 3 GET |
| ServiceRequests | 4 | 3 GET, 1 POST |
| Affiliates | 2 | 1 GET, 1 POST |
| Admin | 2 | 2 GET |
| Webhooks | 2 | 2 POST |
| Total | 79 | (ver tabela completa acima) |
By Auth Type
| Auth Type | Count |
|---|---|
| Public | 8 |
| JWT | 5 |
| JWT + Org | 58 |
| Token (invite) | 3 |
| Webhook Signature | 2 |
| JWT (admin) | 2 |