Referência da API
Documentação completa de todos os endpoints FastAPI do fast_deliv.
Base URL: https://fast-deliv-backend.vercel.app (produção) | http://localhost:8000 (dev)
Todos os endpoints (exceto /health) requerem autenticação via Bearer token JWT do Supabase.
Autenticação
Obter Token JWT
curl -X POST \
"https://<PROJECT>.supabase.co/auth/v1/token?grant_type=password" \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Content-Type: application/json" \
-d '{"email": "admin@example.com", "password": "senha123"}'
Resposta:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600
}
Use o access_token em todas as requisições:
Health Check
GET /health
Verifica se o servidor está operacional. Não requer autenticação.
Resposta 200 OK:
Entregas (/api/v1/deliveries)
POST /api/v1/deliveries — Criar Entrega
Role: admin
Cria uma nova entrega. O backend calcula automaticamente a rota (via ORS) e o ganho do motorista.
curl -X POST http://localhost:8000/api/v1/deliveries \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Entrega Farmácia Central",
"description": "Medicamentos urgentes",
"origin_address": "Rua das Flores, 123 - Centro",
"origin_lat": -23.550520,
"origin_lng": -46.633308,
"destination_address": "Av. Paulista, 1000 - Bela Vista",
"destination_lat": -23.561684,
"destination_lng": -46.655981,
"client_value": 35.00,
"notes": "Ligar antes de chegar"
}'
Resposta 201 Created:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Entrega Farmácia Central",
"description": "Medicamentos urgentes",
"origin_address": "Rua das Flores, 123 - Centro",
"origin_lat": -23.5505200,
"origin_lng": -46.6333080,
"destination_address": "Av. Paulista, 1000 - Bela Vista",
"destination_lat": -23.5616840,
"destination_lng": -46.6559810,
"distance_km": 3.47,
"route_polyline": "mflpDprwhGx...",
"base_fare": 15.00,
"price_per_km": 2.00,
"min_km": 5.00,
"driver_earning": 15.00,
"client_value": 35.00,
"company_profit": 20.00,
"status": "pending",
"driver_id": null,
"created_by": "admin-uuid",
"created_at": "2026-05-18T10:00:00Z",
"wait_since": "2026-05-18T10:00:00Z",
"assigned_at": null,
"started_at": null,
"completed_at": null,
"notes": "Ligar antes de chegar"
}
Erros possíveis:
- 400 — Campos obrigatórios faltando
- 401 — Token inválido
- 403 — Role não é admin
- 502 — Falha ao calcular rota (ORS indisponível)
GET /api/v1/deliveries — Listar Entregas
Role: admin
Retorna todas as entregas ordenadas por created_at DESC.
Resposta 200 OK: Array de DeliveryOut (mesma estrutura do POST).
PATCH /api/v1/deliveries/{id}/assign — Aceitar Entrega
Role: driver
Driver aceita uma entrega pending. Transição: pending → assigned.
curl -X PATCH \
http://localhost:8000/api/v1/deliveries/550e8400-e29b-41d4-a716-446655440000/assign \
-H "Authorization: Bearer $DRIVER_TOKEN"
Resposta 200 OK: DeliveryOut com status: "assigned" e driver_id preenchido.
Erros possíveis:
- 404 — Entrega não encontrada
- 422 — Transição inválida (entrega não está pending)
PATCH /api/v1/deliveries/{id}/start — Iniciar Coleta
Role: driver
Driver confirma que coletou o pacote. Transição: assigned → in_progress.
curl -X PATCH \
http://localhost:8000/api/v1/deliveries/550e8400-e29b-41d4-a716-446655440000/start \
-H "Authorization: Bearer $DRIVER_TOKEN"
Resposta 200 OK: DeliveryOut com status: "in_progress" e started_at preenchido.
PATCH /api/v1/deliveries/{id}/complete — Finalizar Entrega
Role: driver
Driver confirma entrega realizada. Transição: in_progress → completed.
Além de atualizar o status, automaticamente:
1. Insere registro em transactions (earning, credit)
2. Incrementa saldo em wallets via RPC PostgreSQL
curl -X PATCH \
http://localhost:8000/api/v1/deliveries/550e8400-e29b-41d4-a716-446655440000/complete \
-H "Authorization: Bearer $DRIVER_TOKEN"
Resposta 200 OK: DeliveryOut com status: "completed" e completed_at preenchido.
PATCH /api/v1/deliveries/{id}/cancel — Cancelar Entrega
Role: admin
Admin cancela uma entrega. Válido a partir de qualquer estado exceto completed e cancelled.
curl -X PATCH \
http://localhost:8000/api/v1/deliveries/550e8400-e29b-41d4-a716-446655440000/cancel \
-H "Authorization: Bearer $ADMIN_TOKEN"
Resposta 200 OK: DeliveryOut com status: "cancelled".
Carteiras (/api/v1/wallets)
GET /api/v1/wallets/me — Ver Minha Carteira
Role: driver
Retorna o saldo atual da carteira do driver autenticado.
Resposta 200 OK:
GET /api/v1/wallets/me/transactions — Histórico de Transações
Role: driver
Retorna as últimas 50 transações (ganhos, saques, ajustes).
curl http://localhost:8000/api/v1/wallets/me/transactions \
-H "Authorization: Bearer $DRIVER_TOKEN"
Resposta 200 OK:
[
{
"id": "txn-uuid",
"driver_id": "driver-uuid",
"delivery_id": "delivery-uuid",
"type": "earning",
"amount": 29.00,
"direction": "credit",
"status": "completed",
"description": "Ganho entrega #550e8400",
"created_at": "2026-05-18T09:00:00Z"
}
]
POST /api/v1/wallets/withdraw — Solicitar Saque
Role: driver
Cria uma solicitação de saque via Pix. O sistema verifica o saldo e inicia a transferência ASAAS.
curl -X POST http://localhost:8000/api/v1/wallets/withdraw \
-H "Authorization: Bearer $DRIVER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 100.00,
"pix_key": "11999999999",
"pix_key_type": "PHONE"
}'
Tipos de chave Pix aceitos: CPF, CNPJ, EMAIL, PHONE, EVP
Resposta 201 Created:
{
"id": "withdrawal-uuid",
"driver_id": "driver-uuid",
"amount": 100.00,
"pix_key": "11999999999",
"pix_key_type": "PHONE",
"status": "pending",
"asaas_transfer_id": "tra_000012345",
"requested_at": "2026-05-18T10:00:00Z",
"completed_at": null,
"error_message": null
}
Erros possíveis:
- 404 — Carteira não encontrada
- 422 — Saldo insuficiente
- 502 — Falha na transferência ASAAS
Localização (/api/v1/locations)
PUT /api/v1/locations/me — Atualizar Localização
Role: driver
Upsert da localização GPS do driver. Chamado pelo PWA a cada 10 segundos quando online.
curl -X PUT http://localhost:8000/api/v1/locations/me \
-H "Authorization: Bearer $DRIVER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"lat": -23.550520,
"lng": -46.633308,
"heading": 180.0,
"speed": 35.5,
"accuracy": 12.3,
"delivery_id": "550e8400-e29b-41d4-a716-446655440000",
"is_online": true
}'
Resposta 204 No Content
GET /api/v1/locations — Listar Localizações dos Drivers
Role: admin
Retorna a localização atual de todos os drivers online.
Resposta 200 OK:
[
{
"driver_id": "driver-uuid",
"lat": -23.550520,
"lng": -46.633308,
"heading": 180.0,
"speed": 35.5,
"accuracy": 12.3,
"delivery_id": "550e8400-e29b-41d4-a716-446655440000",
"is_online": true,
"updated_at": "2026-05-18T10:05:00Z"
}
]
Motoristas (/api/v1/drivers)
GET /api/v1/drivers — Listar Motoristas
Role: admin
Retorna todos os motoristas com informações de perfil e saldo.
Resposta 200 OK:
[
{
"driver_id": "driver-uuid",
"full_name": "João Silva",
"phone": "11999999999",
"is_active": true,
"balance": 145.50,
"updated_at": "2026-05-18T09:30:00Z"
}
]
Configuração de Preço (/api/v1/pricing)
GET /api/v1/pricing — Obter Configuração Atual
Role: admin
Retorna a configuração de preço mais recente.
Resposta 200 OK:
{
"id": "pricing-uuid",
"base_fare": 15.00,
"price_per_km": 2.00,
"min_km": 5.00,
"updated_at": "2026-05-18T00:00:00Z",
"updated_by": "admin-uuid"
}
PUT /api/v1/pricing — Atualizar Configuração de Preço
Role: admin
Insere nova configuração de preço (mantém histórico).
curl -X PUT http://localhost:8000/api/v1/pricing \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"base_fare": 18.00,
"price_per_km": 2.50,
"min_km": 5.00
}'
Resposta 200 OK: Nova PricingConfigOut.
Webhooks (/api/v1/webhooks)
POST /api/v1/webhooks/asaas — Webhook ASAAS
Endpoint para receber notificações de transferências do ASAAS. Não requer autenticação JWT, mas valida a assinatura HMAC-SHA256 no header asaas-signature.
Eventos processados:
- TRANSFER_DONE / TRANSFER_APPROVED → atualiza withdrawal.status = 'completed'
- TRANSFER_FAILED / TRANSFER_CANCELLED → atualiza withdrawal.status = 'failed'
# Simulação de webhook (para testes)
BODY='{"event":"TRANSFER_DONE","transfer":{"id":"tra_000012345"}}'
SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$ASAAS_WEBHOOK_SECRET" | awk '{print $2}')
curl -X POST http://localhost:8000/api/v1/webhooks/asaas \
-H "Content-Type: application/json" \
-H "asaas-signature: $SIGNATURE" \
-d "$BODY"
Resposta 200 OK:
Schemas de Dados
DeliveryCreate (request)
class DeliveryCreate(BaseModel):
title: str # min_length=1, max_length=200
description: str | None = None
origin_address: str
origin_lat: Decimal
origin_lng: Decimal
destination_address: str
destination_lat: Decimal
destination_lng: Decimal
client_value: Decimal | None = None
notes: str | None = None
WithdrawalRequest (request)
class WithdrawalRequest(BaseModel):
amount: Decimal # gt=0
pix_key: str # min_length=1
pix_key_type: Literal["CPF", "CNPJ", "EMAIL", "PHONE", "EVP"]
LocationUpdate (request)
class LocationUpdate(BaseModel):
lat: Decimal
lng: Decimal
heading: Decimal | None = None
speed: Decimal | None = None
accuracy: Decimal | None = None
delivery_id: str | None = None
is_online: bool = True
Códigos de Erro
| Código | Significado |
|---|---|
400 |
Dados de entrada inválidos |
401 |
Token ausente, inválido ou expirado |
403 |
Role insuficiente para o endpoint |
404 |
Recurso não encontrado |
422 |
Transição de status inválida ou saldo insuficiente |
502 |
Falha em serviço externo (ASAAS ou ORS) |