API Reference
Base path: /api/v1
This page reflects current routes implemented in apps/api/src/routes.
Authentication and Headers
Bearer auth
All protected routes expect:
Authorization: Bearer <supabase_access_token>
Optional operational headers
X-Correlation-Id(request tracing)Idempotency-Key(accepted by CORS policy; explicit enforcement varies by route)
Content type
Content-Type: application/json
Root and Health
GET /
Service info endpoint.
Example response:
{
"service": "salesarc-api",
"links": {
"health": "/health",
"api": "/api/v1"
}
}
GET /health
Health metadata endpoint.
Example response:
{
"status": "ok",
"version": "0.1.0",
"env": "development"
}
Auth
GET /auth/me
Returns user profile and app usability flags for the current session.
Middleware: authProfileMiddleware.
Possible fields:
{
"userId": "uuid",
"role": "consumer",
"tenantIds": ["uuid"],
"status": "active",
"canUseApp": true,
"needsMerchantOnboarding": false,
"email": "user@example.com",
"phone": null,
"code": "PENDING_APPROVAL"
}
code is present only when applicable.
Consumer Routes
Prefix: /consumer
All consumer routes require strict auth middleware and permission checks.
GET /consumer/wallets
Returns wallets owned by authenticated user.
GET /consumer/wallets/:walletId
Returns wallet detail for owned wallet.
GET /consumer/wallets/:walletId/history?limit=20
Returns wallet ledger entries (most recent first).
POST /consumer/wallets/:walletId/redeem/preview
Request body:
{
"pointsToRedeem": 100
}
Returns projected discount and new balance.
POST /consumer/wallets/:walletId/redeem/confirm
Request body:
{
"pointsToRedeem": 100
}
Response:
{
"redemptionCode": "ABC123",
"expiresAt": "2026-04-07T12:30:00.000Z"
}
Client (Merchant) Routes
Prefix: /client
Strict auth required. Tenant-scoped routes also use tenantMiddleware.
Workspace/bootstrap
POST /client/bootstrap-merchant-workspace
Tenant overview and onboarding
GET /client/tenants/:tenantIdPATCH /client/tenants/:tenantId/onboarding
POS connections
GET /client/tenants/:tenantId/pos-connectionsPOST /client/tenants/:tenantId/pos-connections/square/connectDELETE /client/tenants/:tenantId/pos-connections/:connectionId
Reward rules
GET /client/tenants/:tenantId/reward-rulesPOST /client/tenants/:tenantId/reward-rules
Create-rule payload supports:
{
"conversionRate": 1,
"minSpendMinorUnits": 500,
"maxPointsPerTransaction": 500,
"minBalanceToRedeem": 100,
"maxRedemptionPercentage": 100,
"roundingPolicy": "floor",
"effectiveFrom": "2026-04-07T00:00:00.000Z"
}
Analytics and consumers
GET /client/tenants/:tenantId/transactions?limit=50GET /client/tenants/:tenantId/consumers?limit=50
Debug
GET /client/debug/square
Provides non-secret OAuth diagnostics.
Admin Routes
Prefix: /admin
All admin routes require strict auth and admin permissions.
Tenant governance
GET /admin/tenantsGET /admin/tenants/:tenantId
Wallet governance
POST /admin/wallets/:walletId/freezePOST /admin/wallets/:walletId/unfreezePOST /admin/wallets/:walletId/adjust
Adjust payload:
{
"points": -50,
"reason": "manual correction"
}
Audit and user admin
GET /admin/audit-logs?limit=50GET /admin/users/search?q=email-or-mobilePATCH /admin/users/:userId/approvePATCH /admin/users/:userId/role
Role update payload:
{
"role": "client"
}
Webhooks
Prefix: /webhooks
POST /webhooks/square
- optional signature verification via
SQUARE_WEBHOOK_SIGNATURE_KEY - stores raw payload in
pos_webhook_events_raw - returns 200 quickly
- performs async ingest processing
POST /webhooks/clover
Current placeholder returns receive acknowledgement.
OAuth Callback Routes
Prefix: /oauth
GET /oauth/square/callback
Called by Square after merchant consent.
- exchanges code for tokens
- encrypts and upserts
pos_connections - redirects to frontend
/pospage
GET /oauth/clover/callback
Current placeholder redirect with not-implemented status.
Internal Cron
Prefix: /internal/cron
POST /internal/cron/square-poll-payments
Header required:
X-Cron-Secret: <CRON_SECRET>
Runs multi-merchant Square ListPayments fallback/backfill job.
Error Response Shape
Standard API errors use this shape:
{
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"requestId": "req_..."
}
Validation failures may also include issues.