Skip to content

Pre-Alerts API ​

Pre-alerts are the way retailers and marketplaces notify LogirAI of inbound shipments before they arrive at destination. One pre-alert = one Master Air Waybill (MAWB) = many House Air Waybills (HAWBs / guides).

The Pre-Alerts API is the integration surface for client systems. The multipart upload route is onboarded for Chile today; Peru/Argentina Excel parsers are added per client format (a non-CL destination without an onboarded parser β†’ 400 no_parser_for_format). For multi-country ingestion now, use the canonical-JSON endpoint process-pre-alert-json (CL/PE/AR, country derived from destination). The API exposes four endpoints:

MethodPathPurpose
POST/api/public/pre-alerts/v1/uploadSubmit a new pre-alert (Excel manifest + invoice).
GET/api/public/pre-alerts/v1/mawbsList your last 50 MAWBs with per-status guide counts.
GET/api/public/pre-alerts/v1/mawbs/:mawbDetail of one MAWB with the full guide list.
GET/api/public/pre-alerts/v1/guides/:tracking_codeOne guide with its event timeline.

All four require Authorization: Bearer <api_password>. The company is inferred from the token β€” every list and detail endpoint scopes results server-side. See Authentication.


Upload a pre-alert ​

POST /api/public/pre-alerts/v1/upload
Content-Type: multipart/form-data
Authorization: Bearer YOUR_COMPANY_API_PASSWORD

Submits an Excel manifest plus an optional invoice PDF. The MAWB is read from the Excel β€” you don't pass it as a field.

Form fields ​

FieldTypeRequiredDescription
manifest_filefile (.xlsx)yesExcel manifest with HAWB rows. Max 20 MB.
invoice_filefile (.pdf)noInvoice PDF for customs. Max 20 MB.
flight_numberstringnoCarrier flight number (e.g. LA807).
origin_airportstringnoIATA code (e.g. HKG).
destination_airportstringnoIATA code (e.g. SCL).
origin_countrystring (ISO-2)noE.g. CN.
scheduled_departureISO 8601 datetimeno2026-04-18T02:00:00+08:00.
scheduled_arrivalISO 8601 datetimeno2026-04-18T14:00:00-03:00.

Example ​

bash
curl -X POST https://api.logirai.com/api/public/pre-alerts/v1/upload \
  -H "Authorization: Bearer YOUR_COMPANY_API_PASSWORD" \
  -F "manifest_file=@manifest_2026-04.xlsx" \
  -F "invoice_file=@invoice_125-87654321.pdf" \
  -F "flight_number=LA807" \
  -F "origin_airport=HKG" \
  -F "destination_airport=SCL" \
  -F "scheduled_arrival=2026-04-18T14:00:00-03:00"

Response β€” 201 Created ​

json
{
  "success": true,
  "manifest_id": "d4e5f6a7-b8c9-0123-4567-89abcdef0123",
  "flight_id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
  "mawb": "125-87654321",
  "eta": "2026-04-18T14:00:00-03:00",
  "guides_created": 143,
  "guides": [
    { "hawb": "DRL-2026-00001", "tracking_code": "LR2026..." }
  ],
  "rut_invalid_count": 2,
  "warnings": [
    {
      "row_index": 17,
      "hawb": "DRL-2026-00017",
      "field": "consignee_rut",
      "error_code": "rut_invalid_format",
      "severity": "warning",
      "message": "RUT does not match Chilean format β€” guide persisted, flagged for manual review"
    }
  ]
}

warnings aggregates parser warnings and synthetic per-row RUT warnings. A guide with rut_invalid_format is still created and flagged for manual review β€” uploads do not fail because of bad RUTs.

Error responses ​

HTTPerrorWhen
400manifest_file_requiredThe manifest_file field is missing.
400excel_parse_errorExcel is corrupt, encrypted, or unreadable. message carries the parser's reason.
400mawb_not_found_in_fileNo MAWB cell could be located in the Excel.
400validation_failedFlight fields failed validation. details lists the bad fields.
401missing_api_key / invalid_api_keySee Authentication.
400no_parser_for_formatThe destination country has no onboarded multipart parser yet (PE/AR added per client). Use the JSON endpoint meanwhile.
403country_not_allowedThe destination country is not in your allowed_countries.
409mawb_already_existsThis MAWB has already been ingested. Response includes the existing manifest_id.
500internal_server_errorUnexpected failure. Open a support ticket with the timestamp.

Duplicate MAWB

A 409 mawb_already_exists includes the prior manifest_id. Use it with GET /v1/mawbs/:mawb to confirm what's already there before you panic.


List your MAWBs ​

GET /api/public/pre-alerts/v1/mawbs
Authorization: Bearer YOUR_COMPANY_API_PASSWORD

Returns the 50 most recent MAWBs you've uploaded, with totals and per-status guide counts. There are no query parameters in v1 β€” it's a fixed window.

Response β€” 200 OK ​

json
{
  "mawbs": [
    {
      "manifest_id": "d4e5f6a7-b8c9-0123-4567-89abcdef0123",
      "mawb": "125-87654321",
      "status": "in_transit",
      "eta": "2026-04-18T14:00:00-03:00",
      "total_guides": 143,
      "total_weight_kg": 412.5,
      "total_pieces": 143,
      "total_fob_usd": 18432.27,
      "guides_by_status": {
        "in_transit": 140,
        "customs_held": 3
      },
      "created_at": "2026-04-15T10:00:00Z"
    }
  ]
}

guides_by_status is a map of <status>: <count>, summed across all guides in that MAWB. Use it as the primary signal for "is this batch healthy" without paginating through every guide.

If you have no MAWBs yet, the response is { "mawbs": [] }.


Get one MAWB ​

GET /api/public/pre-alerts/v1/mawbs/:mawb
Authorization: Bearer YOUR_COMPANY_API_PASSWORD

Path param is the MAWB number (e.g. 125-87654321).

Response β€” 200 OK ​

json
{
  "manifest_id": "d4e5f6a7-b8c9-0123-4567-89abcdef0123",
  "mawb": "125-87654321",
  "status": "in_transit",
  "eta": "2026-04-18T14:00:00-03:00",
  "total_guides": 143,
  "total_weight_kg": 412.5,
  "total_pieces": 143,
  "total_fob_usd": 18432.27,
  "guides_by_status": { "in_transit": 140, "customs_held": 3 },
  "guides": [
    {
      "hawb": "DRL-2026-00001",
      "tracking_code": "LR2026A1B2C3",
      "status": "in_transit",
      "status_code": 4
    }
  ]
}

Errors ​

HTTPerrorWhen
404not_foundThe MAWB is not yours, or doesn't exist.

Get one guide (by tracking code) ​

GET /api/public/pre-alerts/v1/guides/:tracking_code
Authorization: Bearer YOUR_COMPANY_API_PASSWORD

Returns one guide with its full event timeline. The tracking_code is the LogirAI-issued identifier you got back from the upload response (guides[].tracking_code).

Response β€” 200 OK ​

json
{
  "hawb": "DRL-2026-00001",
  "tracking_code": "LR2026A1B2C3",
  "mawb": "125-87654321",
  "status": "delivered",
  "status_code": 6,
  "consignee_name": "MarΓ­a GonzΓ‘lez",
  "weight_kg": 2.75,
  "packages_count": 1,
  "description_original": "Bluetooth Speaker",
  "fob_usd": 29.99,
  "events": [
    { "status": "registered", "status_code": 1, "timestamp": "2026-04-15T10:00:01Z", "source": "pre_alert" },
    { "status": "in_transit", "status_code": 4, "timestamp": "2026-04-16T18:30:00Z", "source": "carrier" },
    { "status": "customs_released", "status_code": 3, "timestamp": "2026-04-18T11:20:00Z", "source": "customs" },
    { "status": "out_for_delivery", "status_code": 5, "timestamp": "2026-04-19T08:15:00Z", "source": "courier_scan" },
    { "status": "delivered", "status_code": 6, "timestamp": "2026-04-19T11:45:00Z", "source": "courier_scan" }
  ]
}

Errors ​

HTTPerrorWhen
404not_foundThe tracking code is not yours, or doesn't exist.

Status reference ​

The status and status_code fields you'll see across responses:

CodestatusMeaning
1registeredPre-alert ingested; guide created.
2customs_processingAwaiting clearance.
3customs_releasedCleared by customs.
4in_transitMoving (international or domestic leg).
5out_for_deliveryWith last-mile carrier for final delivery.
6deliveredDelivered to consignee.

Exception states like customs_held may appear in guides_by_status and on the timeline.


Polling vs webhooks ​

The four GET endpoints are the system of record β€” always treat them as authoritative. Webhooks are an optimization to avoid frequent polling.

  • For at-a-glance dashboards: poll /v1/mawbs every few minutes.
  • For per-shipment live updates: subscribe to Client Webhooks and reconcile on a slower cadence.
  • For one-off lookups (customer asks "where's my package?"): hit /v1/guides/:tracking_code on demand.

LogirAI β€” Cross-Border Logistics API for Retailers and Marketplaces