API Reference

Integrate your plant with Orderafy

Create transfer orders, receive delivery confirmations and check the status of every unit with its photo evidence. Everything over HTTPS with JSON.

Base URL:https://orderafy.app/api/v1
API v1

Introduction

Orderafy manages unit transfers between plants and dealers with verifiable photo evidence. This API lets your system create orders, receive delivery confirmations and check the status of every unit at any time.

All responses are JSON. Errors use a uniform format with the error field. Integration runs over HTTPS with a per-client API key; the operator app and the portal use their own authentication schemes (see Authentication).

Order lifecycle

The integration creates the order without an operator (imported status); assignment is done by the dispatcher in the portal. The normal cycle is:

importedImported — created by the API, no operator assigned
assignedAssigned — the dispatcher assigned an operator
in_transitIn transit — the operator received the unit and is on the way
deliveredDelivered — confirmed via webhook or field closure
on_holdOn hold — paused by the dispatcher
staleNo activity
cancelledCancelled — delivery cannot be confirmed

Locked evidence

Every receipt and delivery requires verifiable photos before closing the order: the evidence summary (receiptPhotos, deliveryPhotos, incidentPhotos, signedOrderPhoto) travels in every status response.

Authentication

The API uses three schemes depending on the integration type. Each endpoint states which one it requires.

X-API-Key

API key (X-API-Key)

For integration endpoints (/orders, /webhooks/delivery). Sent in the X-API-Key header. The key is delivered ONCE when generated (npm run api:key); if lost, it is revoked and a new one is generated.

Bearer

Operator JWT (Bearer)

For operator app endpoints (/api/operators/...). Sent as Authorization: Bearer <token>. The token's operator must match the route's operator.

cookie

Portal session (cookie)

For monitoring, reporting and administration endpoints (/api/ordenes/..., /api/reports/..., /api/admin/...). Uses the portal session cookie; the required role (admin, staff or dealer) is stated per endpoint.

Integration

Endpoints for the client system: create orders, check status and confirm deliveries. API key authentication.

POST/orders

Create a transfer order

Registers a transfer order using the client system's order number. If orderNumber already exists it responds 409 (status lookups use GET /orders/{orderNumber}). Orders are created without a driver (imported status); assignment is done by the dispatcher in the portal.

Authentication: API key

Request · Example

JSON
{
  "orderNumber": "INT-2026-0831-001",
  "origin": "Planta Escobedo, Nuevo León",
  "destination": "Distribuidor International Monterrey, NL",
  "unitVIN": "3HCDZAPR9SL123456",
  "unitDescription": "Camión International HV 2026",
  "dealerName": "International Monterrey",
  "scheduledDate": "2026-08-31",
  "observations": "Entrega programada antes de las 12:00"
}

curl

bash
curl -X POST https://orderafy.app/api/v1/orders \
  -H "Content-Type: application/json" \
  -H "X-API-Key: TU_API_KEY" \
  -d '{
    "orderNumber": "INT-2026-0831-001",
    "origin": "Planta Escobedo, Nuevo León",
    "destination": "Distribuidor International Monterrey, NL",
    "unitVIN": "3HCDZAPR9SL123456",
    "unitDescription": "Camión International HV 2026",
    "dealerName": "International Monterrey",
    "scheduledDate": "2026-08-31",
    "observations": "Entrega programada antes de las 12:00"
  }'

Response · Example

JSON
{
  "order": {
    "id": "42",
    "orderNumber": "INT-2026-0831-001",
    "unitVIN": "3HCDZAPR9SL123456",
    "unitDescription": "Camión International HV 2026",
    "origin": "Planta Escobedo, Nuevo León",
    "destination": "Distribuidor International Monterrey, NL",
    "dealerName": "International Monterrey",
    "status": "imported",
    "driver": null,
    "scheduledDate": "2026-08-31",
    "receivedAt": null,
    "deliveredAt": null,
    "dieselLiters": null,
    "observations": "Entrega programada antes de las 12:00",
    "createdAt": "2026-08-31T09:12:00-06:00",
    "updatedAt": "2026-08-31T09:12:00-06:00"
  },
  "evidence": {
    "receiptPhotos": 0,
    "deliveryPhotos": 0,
    "incidentPhotos": 0,
    "signedOrderPhoto": false
  },
  "incidents": []
}

Responses

201Order created (initial status and empty evidence)
400Missing required fields or invalid format
401Missing or invalid API key
409An order with that orderNumber already exists
503Database unavailable
GET/orders/{orderNumber}

Get an order status

Returns the order data, its status, the assigned driver (if any), the photo evidence summary and open/resolved incidents. This is the main tracking endpoint for the client system.

Authentication: API key

Parameters

orderNumber
path
string
Required
Order number, exactly as sent when the order was created

curl

bash
curl https://orderafy.app/api/v1/orders/INT-2026-0831-001 \
  -H "X-API-Key: TU_API_KEY"

Response · Example

JSON
{
  "order": {
    "id": "42",
    "orderNumber": "INT-2026-0831-001",
    "unitVIN": "3HCDZAPR9SL123456",
    "unitDescription": "Camión International HV 2026",
    "origin": "Planta Escobedo, Nuevo León",
    "destination": "Distribuidor International Monterrey, NL",
    "dealerName": "International Monterrey",
    "status": "in_transit",
    "driver": {
      "name": "Carlos Ramírez",
      "phone": "+52 81 1234 5678"
    },
    "scheduledDate": "2026-08-31",
    "receivedAt": "2026-08-31T10:05:00-06:00",
    "deliveredAt": null,
    "dieselLiters": 385,
    "observations": "Entrega programada antes de las 12:00",
    "createdAt": "2026-08-31T09:12:00-06:00",
    "updatedAt": "2026-08-31T10:05:00-06:00"
  },
  "evidence": {
    "receiptPhotos": 3,
    "deliveryPhotos": 4,
    "incidentPhotos": 0,
    "signedOrderPhoto": true
  },
  "incidents": []
}

Responses

200Full order status
401Missing or invalid API key
404The order does not exist
503Database unavailable
POST/webhooks/delivery

Delivery confirmation (webhook)

The client system notifies that the unit arrived at its destination; Orderafy closes the order as delivered. Every call is logged in the webhook journal (full payload) for traceability. Idempotent: if the order was already delivered it responds 200 with alreadyDelivered: true and no changes. Retry with exponential backoff (1s, 2s, 4s…) on 503 and 5xx; do not retry on 400/401/404/409.

Authentication: API key

Request · Example

JSON
{
  "orderNumber": "INT-2026-0831-001",
  "deliveredAt": "2026-08-31T16:45:00-06:00",
  "receivedBy": "Almacén de producto terminado",
  "reference": "GR-88213",
  "observations": "Unidad sin novedad"
}

curl

bash
curl -X POST https://orderafy.app/api/v1/webhooks/delivery \
  -H "Content-Type: application/json" \
  -H "X-API-Key: TU_API_KEY" \
  -d '{
    "orderNumber": "INT-2026-0831-001",
    "deliveredAt": "2026-08-31T16:45:00-06:00",
    "receivedBy": "Almacén de producto terminado",
    "reference": "GR-88213",
    "observations": "Unidad sin novedad"
  }'

Response · Example

JSON
{
  "order": {
    "id": "42",
    "orderNumber": "INT-2026-0831-001",
    "status": "delivered",
    "deliveredAt": "2026-08-31T16:45:00-06:00"
  },
  "evidence": {
    "receiptPhotos": 3,
    "deliveryPhotos": 4,
    "incidentPhotos": 0,
    "signedOrderPhoto": true
  },
  "incidents": [],
  "alreadyDelivered": false
}

Responses

200Delivery confirmed (or already confirmed)
400Invalid body (orderNumber required, deliveredAt ISO-8601)
401Missing or invalid API key
404The order does not exist (the event stays in the journal)
409The order is cancelled; delivery cannot be confirmed
503Database unavailable

Telemetry

Server-driven config, consent, route and driving event ingestion, plus score and heatmap reports.

GET/api/config

Server-driven config for the driver app

Returns the client's active catalogs (photo sections, vehicle attributes and inspection items) ordered by sort_order. Dual authentication: driver JWT or portal session.

Authentication: Operator JWT

Parameters

tenant
query
string
Optional
Client slug (defaults to the portal's client)
default: cliente del portal
moment
query
string
Optional
Filters by moment (applies_to IN (moment, 'both')); omitting returns all
receipt | delivery

curl

bash
curl https://orderafy.app/api/v1/api/config \
  -H "Authorization: Bearer JWT_DEL_CHOFER"

Response · Example

JSON
{
  "tenant": { "id": "1", "name": "Orderafy" },
  "moment": null,
  "sections": [
    {
      "id": "1",
      "tenantId": "1",
      "code": "front",
      "title": "Frente (exterior)",
      "description": null,
      "appliesTo": "both",
      "required": true,
      "minPhotos": 1,
      "maxPhotos": 2,
      "sortOrder": 2,
      "active": true
    }
  ],
  "vehicleFields": [
    {
      "id": "1",
      "tenantId": "1",
      "code": "diesel_level",
      "label": "Nivel de diésel",
      "unit": "%",
      "required": true,
      "appliesTo": "both",
      "sortOrder": 1,
      "active": true
    }
  ],
  "inspectionItems": [
    {
      "id": "1",
      "tenantId": "1",
      "code": "scratches",
      "label": "Rayones",
      "category": "carrocería",
      "states": [{ "value": "minor", "label": "Daño menor" }],
      "requiresPhoto": true,
      "appliesTo": "both",
      "sortOrder": 1,
      "active": true
    }
  ]
}

Responses

200Client catalogs
400Invalid moment or disabled client
401Not authenticated (neither driver JWT nor portal session)
404Client not found
GET/api/drivers/{driverId}/telemetria

Telemetry config + driver consent

Consumed by the driver app on open: the config builds the privacy notice and the adaptive GPS interval (server-driven); the consent decides whether tracking may start. consent is null if the driver has not accepted the notice yet.

Authentication: Operator JWT

Parameters

driverId
path
integer
Required
Driver id (drivers.id); must match the token's driver

Response · Example

JSON
{
  "tenant": { "id": "1", "name": "Orderafy" },
  "config": {
    "tenantId": "1",
    "gpsTrackingEnabled": true,
    "gpsIntervalSec": 20,
    "gpsAdaptive": true,
    "driverEventsEnabled": true,
    "overspeedLimitKmh": 95,
    "appEventsEnabled": true,
    "consentRequired": true,
    "retentionDays": 90,
    "scoreWeights": { "hard_brake": 8, "hard_accel": 6, "sharp_curve": 10, "overspeed": 12 },
    "updatedAt": "2026-08-31T09:00:00-06:00"
  },
  "consent": {
    "id": "3",
    "driverId": "2",
    "version": "v2",
    "gpsOk": true,
    "behaviorOk": true,
    "analyticsOk": false,
    "acceptedAt": "2026-08-28T11:20:00-06:00"
  },
  "noticeVersion": "v2",
  "fetchedAt": "2026-08-31T09:12:00-06:00"
}

Responses

200Config + consent
401No valid JWT
403The token does not match the route's driver
503Database unavailable
POST/api/drivers/{driverId}/tracks

Track points ingestion (batch)

Idempotent via UNIQUE (order_id, device_ts): retrying the same batch (same batchId) does not duplicate points. Validations: every order in the batch belongs to the driver and is in transit; consent must be current; lat/lng in range; deviceTs no more than 5 min in the future. The whole batch is rejected if consent was revoked or telemetry is disabled.

Authentication: Operator JWT

Parameters

driverId
path
integer
Required
Driver id

Request · Example

JSON
{
  "batchId": "3f2a1c4e-9b7d-4e5a-8f0c-1d2e3f4a5b6c",
  "points": [
    {
      "orderId": 42,
      "lat": 25.7894,
      "lng": -100.2653,
      "speedKmh": 62,
      "heading": 214,
      "accuracyM": 4.2,
      "source": "gps",
      "deviceTs": "2026-08-31T14:05:10-06:00"
    }
  ]
}

Response · Example

JSON
{
  "accepted": 30,
  "duplicates": 0
}

Responses

202Batch accepted (accepted + duplicates)
400Invalid payload or point (order not in transit, coordinates out of range, future deviceTs…)
401No valid JWT
403Another driver's token, telemetry disabled or consent revoked
503Database unavailable
POST/api/drivers/{driverId}/events

Driving events ingestion (batch)

Driving behavior events detected by the driver app (hard brakes, accelerations, sharp curves, overspeed). Idempotent via UNIQUE (order_id, device_ts, type). Same validations as tracks: order in transit, current consent and type within the enum.

Authentication: Operator JWT

Parameters

driverId
path
integer
Required
Driver id

Request · Example

JSON
{
  "batchId": "3f2a1c4e-9b7d-4e5a-8f0c-1d2e3f4a5b6c",
  "events": [
    {
      "orderId": 42,
      "type": "hard_brake",
      "lat": 25.7894,
      "lng": -100.2653,
      "magnitude": 0.62,
      "deviceTs": "2026-08-31T14:22:41-06:00"
    }
  ]
}

Response · Example

JSON
{
  "accepted": 30,
  "duplicates": 0
}

Responses

202Batch accepted (accepted + duplicates)
400Invalid payload or event (order not in transit, type outside enum, future deviceTs…)
401No valid JWT
403Another driver's token, events disabled or behavior consent revoked
503Database unavailable
GET/api/ordenes/{id}/recorrido

Order route (polyline + statistics)

Route map: points ordered by device_ts, real distance (Haversine sum), duration, stop zones (speed < 5 km/h for > 2 min) and estimated origin→destination distance. Admin/monitoring role (admin|staff|dealer; dealers only see their own orders).

Authentication: Portal session

Parameters

id
path
integer
Required
Order id

Response · Example

JSON
{
  "orden": {
    "id": "42",
    "orderNumber": "INT-2026-0831-001",
    "status": "in_transit",
    "origin": "Planta Escobedo, Nuevo León",
    "destination": "Distribuidor International Monterrey, NL",
    "dealerName": "International Monterrey",
    "unitVin": "3HCDZAPR9SL123456",
    "unitDescription": "Camión International HV 2026",
    "driverId": "2",
    "driverName": "Carlos Ramírez"
  },
  "points": [
    {
      "lat": 25.7894,
      "lng": -100.2653,
      "speedKmh": 62,
      "heading": 214,
      "accuracyM": 4.2,
      "source": "gps",
      "deviceTs": "2026-08-31T14:05:10-06:00"
    }
  ],
  "stats": {
    "points": 182,
    "distanceKm": 48.3,
    "durationSec": 5220,
    "startTs": "2026-08-31T12:40:00-06:00",
    "endTs": "2026-08-31T14:07:00-06:00",
    "stops": [
      {
        "lat": 25.7911,
        "lng": -100.2584,
        "startTs": "2026-08-31T13:15:00-06:00",
        "endTs": "2026-08-31T13:22:00-06:00",
        "durationSec": 420,
        "avgSpeedKmh": 0
      }
    ],
    "estimatedDistanceKm": null
  }
}

Responses

200Order route
400Invalid id
401No portal session
404Order not found or outside the dealer's scope
503Database unavailable
GET/api/ordenes/{id}/eventos

Order driving events (with acknowledged status)

Lists an order's driving behavior events (hard brakes, accelerations, sharp curves, overspeed) with their acknowledged status for monitoring. Ordered by device_ts descending. Admin/monitoring role.

Authentication: Portal session

Parameters

id
path
integer
Required
Order id

Response · Example

JSON
{
  "orderId": 42,
  "orderNumber": "INT-2026-0831-001",
  "events": [
    {
      "id": "128",
      "orderId": 42,
      "driverId": 2,
      "driverName": "Carlos Ramírez",
      "type": "hard_brake",
      "lat": 25.7894,
      "lng": -100.2653,
      "magnitude": 0.62,
      "deviceTs": "2026-08-31T14:22:41-06:00",
      "receivedAt": "2026-08-31T14:22:42-06:00",
      "acknowledged": true
    }
  ],
  "total": 1
}

Responses

200Order events
400Invalid id
401No portal session
404Order not found or outside the dealer's scope
503Database unavailable
POST/api/ordenes/{id}/eventos/{eventId}/ack

Acknowledge or dismiss a driving event

Monitoring acknowledges (acknowledged: true) or dismisses (false) an order's driving event. Admin/monitoring role (dealers only on their own orders).

Authentication: Portal session

Parameters

id
path
integer
Required
Order id
eventId
path
integer
Required
Driving event id

Request · Example

JSON
{
  "acknowledged": true
}

Response · Example

JSON
{
  "id": "128",
  "orderId": 42,
  "driverId": 2,
  "driverName": "Carlos Ramírez",
  "type": "hard_brake",
  "lat": 25.7894,
  "lng": -100.2653,
  "magnitude": 0.62,
  "deviceTs": "2026-08-31T14:22:41-06:00",
  "receivedAt": "2026-08-31T14:22:42-06:00",
  "acknowledged": true
}

Responses

200Event updated
400Invalid id or body
401No portal session
404Order or event not found
503Database unavailable
GET/api/reports/telemetria/score

Driving score 0–100 + weekly trend + driving mode

Driving score (Geotab pattern): max(0, 100 − Σ(weight × N/km) × 100), normalized per 100 km using real km from order_tracks. Weights from score_weights (defaults: hard_brake 8, hard_accel 6, sharp_curve 10, overspeed 12). Score is null if km < 50 in the period (not enough data). Without driverId it returns the fleet aggregate; per-driver breakdown requires the admin role.

Authentication: Portal session

Parameters

driverId
query
integer
Optional
Per-driver breakdown (requires admin role)
from
query
string
Optional
Period start (ISO 8601)
to
query
string
Optional
Period end (ISO 8601); defaults to now

Response · Example

JSON
{
  "driverId": null,
  "from": "2026-06-01T00:00:00-06:00",
  "to": "2026-08-31T23:59:59-06:00",
  "km": 4820.5,
  "events": { "hard_brake": 3, "hard_accel": 1, "sharp_curve": 0, "overspeed": 0 },
  "weights": { "hard_brake": 8, "hard_accel": 6, "sharp_curve": 10, "overspeed": 12 },
  "score": 92,
  "trend": [
    { "weekStart": "2026-08-03", "km": 610.2, "events": { "hard_brake": 1, "hard_accel": 0, "sharp_curve": 0, "overspeed": 0 }, "score": 97 },
    { "weekStart": "2026-08-10", "km": 655.8, "events": { "hard_brake": 2, "hard_accel": 1, "sharp_curve": 0, "overspeed": 0 }, "score": 94 }
  ],
  "drivingModes": {
    "urbano": { "segments": 24, "km": 320.1 },
    "mixto": { "segments": 18, "km": 890.4 },
    "carretera": { "segments": 9, "km": 3610.0 }
  }
}

Responses

200Score, trend and driving modes
400Invalid parameters
401No portal session
403Per-driver breakdown without admin role
503Database unavailable
GET/api/reports/telemetria/heatmap

Route activity heatmap

Points aggregated by ~4-decimal cell (≈ 11 m). Aggregated by default (privacy); the per-driver filter (breakdown) requires the admin role. Without from, the default period is the last 90 days (retention).

Authentication: Portal session

Parameters

driverId
query
integer
Optional
Per-driver breakdown (requires admin role)
from
query
string
Optional
Period start (ISO 8601)
to
query
string
Optional
Period end (ISO 8601); defaults to now

Response · Example

JSON
{
  "points": [
    { "lat": 25.7894, "lng": -100.2653, "count": 12, "intensity": 0.8 }
  ],
  "total": 240,
  "from": "2026-06-01T00:00:00-06:00",
  "to": "2026-08-31T23:59:59-06:00",
  "driverId": null
}

Responses

200Aggregated cells
400Invalid parameters
401No portal session
403Per-driver breakdown without admin role
503Database unavailable

Catalogs

Server-driven catalog administration (photo sections, vehicle attributes, inspection checklist) and telemetry configuration. Admin role.

GETPOST/api/admin/evidence-sections

Photo sections (list / create)

Server-driven catalog of evidence photo sections (receipt and delivery). GET lists including inactive ones; POST creates with the admin role.

Authentication: Portal sessionAdmin role

Parameters

tenant_id
query
integer
Optional
Filters by client; omitting returns all

Request · Example

JSON
{
  "code": "front",
  "title": "Frente (exterior)",
  "description": null,
  "applies_to": "both",
  "required": true,
  "min_photos": 1,
  "max_photos": 2,
  "sort_order": 2,
  "active": true
}

Responses

200Photo sections (GET)
201Section created (POST)
400Invalid payload or invalid/disabled client
403Admin role required
409Duplicate code for the client
PUTDELETE/api/admin/evidence-sections/{id}

Photo section by id (update / delete)

PUT updates (partial fields accepted); DELETE removes. 409 if the code is in use by existing orders — in that case deactivate it with active=false.

Authentication: Portal sessionAdmin role

Parameters

id
path
integer
Required
Section id

Request · Example

JSON
{
  "title": "Frente (exterior)",
  "active": false
}

Response · Example

JSON
{
  "deleted": true
}

Responses

200Section updated (PUT) or deleted (DELETE)
404Section does not exist
409Code in use by orders (DELETE)
GETPOST/api/admin/inspection-items

Inspection items (list / create)

Server-driven catalog of the unit inspection checklist. GET lists including inactive ones; POST creates with the admin role.

Authentication: Portal sessionAdmin role

Parameters

tenant_id
query
integer
Optional
Filters by client; omitting returns all

Request · Example

JSON
{
  "code": "scratches",
  "label": "Rayones",
  "category": "carrocería",
  "states": [{ "value": "minor", "label": "Daño menor" }],
  "requires_photo": true,
  "applies_to": "both",
  "sort_order": 1,
  "active": true
}

Responses

200Inspection items (GET)
201Item created (POST)
400Invalid payload or invalid/disabled client
403Admin role required
409Duplicate code for the client
PUTDELETE/api/admin/inspection-items/{id}

Inspection item by id (update / delete)

PUT updates (partial fields accepted); DELETE removes. 409 if the code is in use by existing orders — in that case deactivate it with active=false.

Authentication: Portal sessionAdmin role

Parameters

id
path
integer
Required
Item id

Request · Example

JSON
{
  "label": "Rayones",
  "active": false
}

Response · Example

JSON
{
  "deleted": true
}

Responses

200Item updated (PUT) or deleted (DELETE)
404Item does not exist
409Code in use by orders (DELETE)
GETPOST/api/admin/vehicle-fields

Vehicle attributes (list / create)

Server-driven catalog of vehicle data attributes (text, number, select, date). GET lists including inactive ones; POST creates with the admin role.

Authentication: Portal sessionAdmin role

Parameters

tenant_id
query
integer
Optional
Filters by client; omitting returns all

Request · Example

JSON
{
  "code": "diesel_level",
  "label": "Nivel de diésel",
  "field_type": "select",
  "unit": "%",
  "options": [{ "value": "low", "label": "Bajo" }, { "value": "full", "label": "Lleno" }],
  "required": true,
  "applies_to": "both",
  "sort_order": 1,
  "active": true
}

Responses

200Vehicle attributes (GET)
201Attribute created (POST)
400Invalid payload or invalid/disabled client
403Admin role required
409Duplicate code for the client
PUTDELETE/api/admin/vehicle-fields/{id}

Vehicle attribute by id (update / delete)

PUT updates (partial fields accepted); DELETE removes. 409 if the code is in use by existing orders — in that case deactivate it with active=false.

Authentication: Portal sessionAdmin role

Parameters

id
path
integer
Required
Attribute id

Request · Example

JSON
{
  "label": "Nivel de diésel",
  "active": false
}

Response · Example

JSON
{
  "deleted": true
}

Responses

200Attribute updated (PUT) or deleted (DELETE)
404Attribute does not exist
409Code in use by orders (DELETE)
GETPUT/api/admin/telemetria

Client telemetry config (admin role)

GET returns the client config; PUT updates it (partial update, upsert if the row does not exist). score_weights merges with the current weights.

Authentication: Portal sessionAdmin role

Parameters

tenant_id
query
integer
Optional
Client; omitting = first active client

Request · Example

JSON
{
  "gpsTrackingEnabled": true,
  "gpsIntervalSec": 20,
  "gpsAdaptive": true,
  "driverEventsEnabled": true,
  "overspeedLimitKmh": 95,
  "appEventsEnabled": true,
  "consentRequired": true,
  "retentionDays": 90,
  "scoreWeights": { "hard_brake": 8, "hard_accel": 6, "sharp_curve": 10, "overspeed": 12 }
}

Responses

200Client config (GET/PUT)
400Invalid payload (PUT)
401No portal session
403Admin role required
404No config for the client (GET)
503Database unavailable

Health

Public operational endpoints to validate the link and fetch the specification.

GET/health

Public health check

Checks connectivity with the API and its database. No authentication; useful to validate the link before integrating.

Authentication: PublicPublic

curl

bash
curl https://orderafy.app/api/v1/health

Response · Example

JSON
{
  "status": "ok",
  "service": "orderafy-api-v1",
  "database": true,
  "time": "2026-08-31T16:00:00-06:00"
}

Responses

200API and database available
503API up but database unavailable
GET/openapi

OpenAPI 3.1 specification (YAML)

This same document, served as plain text. Can be pasted into editor.swagger.io or imported into Postman to generate the client.

Authentication: PublicPublic

curl

bash
curl https://orderafy.app/api/v1/openapi

Responses

200OpenAPI document in YAML

Agentes de IA — Servidor MCP

Conecta cualquier agente de IA (Claude, Codex, asistentes propios) a Orderafy con el servidor MCP: órdenes, operadores, incidencias, evidencia con candado, PDFs y estado del ambiente — autenticado con tu API key por tenant y ambiente. Escribir en producción siempre requiere confirmación explícita.

Descarga el servidor

orderafy-mcp-cliente.zip

Incluye: paquete Python (whl), guía de instalación para clientes y ejemplo de uso. Requiere Python ≥ 3.11 y tu API key de Orderafy.

Configuración

BASH
export ORDERAFY_API_TOKEN_PROD="ord_live_TU_TOKEN"
orderafy-mcp

Ambientes: dev, qa, demo, prod. Un token solo funciona en su ambiente. Solicita tu API key al equipo Azimutha.

Herramientas del servidor (13)

list_ordersÓrdenes con totales por estatus
get_order_detailOrden + unidades + evidencia + incidencias
check_order_pdf¿Checklist adjunto? Campos extraídos
reprocess_pdfRe-extrae direcciones/geo/unidad del PDF
assign_driverAsigna / reasigna / desasigna operador
update_order_statusCancela o pone en espera
request_reevidenceSolicita recaptura de evidencia
list_driversOperadores + orden activa + GPS
get_driver_locationÚltima posición GPS
list_incidentsIncidencias con filtros
get_evidenceProgreso, fotos con SHA-256, checklist
get_environment_statusSalud del ambiente
check_ocr_statusSalud del servicio OCR

Errors

All errors use the same format: a JSON object with the error field and a readable message.

Error format

JSON
{
  "error": "No existe la orden 'INT-2026-0831-001'."
}

Retries on /webhooks/delivery are safe (idempotent): retry with backoff on 503 and 5xx; do not retry on 400/401/404/409.

Common status codes

400Bad request: missing required fields or invalid format
401Missing or invalid authentication (API key, JWT or session)
403Forbidden: the role does not allow the operation
404Resource not found (order, operator, catalog or config)
409State conflict: duplicate, code in use or cancelled order
503Database unavailable: retry with exponential backoff (1s, 2s, 4s…)