# API v1 Quickstart

## Purpose

This is the shortest path to integrate with the FlowMint public container tracking API.

Target public host:
- `https://api.cargoflowplus.com`

Temporary production host until DNS is live:
- `https://flowmint.cargoflowplus.com`

## Authentication

All requests use a consumer token:

```http
Authorization: Bearer <consumer-token>
```

## 1. Start Tracking

```bash
curl -sS -X POST "https://flowmint.cargoflowplus.com/api/v1/containers/track" \
  -H "Authorization: Bearer <consumer-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "container_number": "TXGU7408862",
    "client_reference": "shipment-123"
  }'
```

Example response:

```json
{
  "tracking_id": "WATCH-CONTAINER-20260413-ABC123",
  "container_number": "TXGU7408862",
  "status": "tracking",
  "created": true,
  "poll_interval_minutes": 180,
  "next_run_at": "2026-04-13T10:15:00Z",
  "source_hint": null,
  "carrier_scac": null,
  "status_url": "/api/v1/containers/TXGU7408862",
  "timeline_url": "/api/v1/containers/TXGU7408862/timeline"
}
```

## 2. Get Current Status

```bash
curl -sS "https://flowmint.cargoflowplus.com/api/v1/containers/TXGU7408862" \
  -H "Authorization: Bearer <consumer-token>"
```

Example response:

```json
{
  "tracking_id": "WATCH-CONTAINER-20260413-ABC123",
  "container_number": "TXGU7408862",
  "carrier_scac": "COSU",
  "vessel_name": "CSCL MARS",
  "destination_port": "Rotterdam (NLRTM)",
  "completed": true,
  "last_fetched_at": "2026-04-13T10:18:00Z",
  "latest_snapshot_id": "SNAP-20260413-XYZ987",
  "watch_status": "completed",
  "journey_state": "returned",
  "current_status": {
    "code": "EMPTY_RETURNED",
    "label": "Empty returned",
    "location": "Duesseldorf (DE)",
    "event_time": "2026-04-09T00:00:00Z",
    "source": "shipmentlink"
  },
  "eta": {
    "final_pod_eta": "2026-03-24T10:24:00Z",
    "source": "shipmentlink",
    "confidence": "high",
    "basis": "confirmed_ata"
  },
  "source": {
    "selected_source": "shipmentlink",
    "detected_source": "shipmentlink",
    "result_code": "success"
  },
  "metadata": {
    "current_phase": "container_led"
  }
}
```

## 3. Get Timeline

```bash
curl -sS "https://flowmint.cargoflowplus.com/api/v1/containers/TXGU7408862/timeline" \
  -H "Authorization: Bearer <consumer-token>"
```

Example response:

```json
{
  "tracking_id": "WATCH-CONTAINER-20260413-ABC123",
  "container_number": "TXGU7408862",
  "completed": true,
  "summary": {
    "journey_state": "returned",
    "current_status": "Empty returned",
    "current_location": "Duesseldorf (DE)",
    "destination_port": "Rotterdam (NLRTM)",
    "final_pod_eta": "2026-03-24T10:24:00Z",
    "source": "shipmentlink"
  },
  "milestones": [
    {
      "milestone_code": "ARRIVED_TERMINAL",
      "label": "Arrived terminal",
      "location": "Rotterdam (NLRTM)",
      "event_time": "2026-03-24T10:24:00Z",
      "source": "shipmentlink",
      "details": "Empty container returned"
    },
    {
      "milestone_code": "DISCHARGED",
      "label": "Discharged",
      "location": "Rotterdam (NLRTM)",
      "event_time": "2026-03-25T09:00:00Z",
      "source": "shipmentlink",
      "details": "Empty container returned"
    },
    {
      "milestone_code": "GATE_OUT",
      "label": "Gate out",
      "location": "Duesseldorf (DE)",
      "event_time": "2026-04-09T00:00:00Z",
      "source": "shipmentlink",
      "details": "Empty container returned"
    },
    {
      "milestone_code": "EMPTY_RETURNED",
      "label": "Empty returned",
      "location": "Duesseldorf (DE)",
      "event_time": "2026-04-09T00:00:00Z",
      "source": "shipmentlink",
      "details": "Empty container returned"
    }
  ]
}
```

## 4. Register a Webhook

```bash
curl -sS -X POST "https://flowmint.cargoflowplus.com/api/v1/subscriptions/webhooks" \
  -H "Authorization: Bearer <consumer-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint_url": "https://client.example.com/webhooks/flowmint",
    "signing_secret": "replace-me-with-a-random-secret",
    "event_filters": ["container.updated", "container.completed"]
  }'
```

Example event envelope:

```json
{
  "event": "container.updated",
  "occurred_at": "2026-04-13T10:18:00Z",
  "tracking_id": "WATCH-CONTAINER-20260413-ABC123",
  "container_number": "TXGU7408862",
  "journey_state": "left_terminal",
  "data": {
    "status_url": "/api/v1/containers/TXGU7408862",
    "timeline_url": "/api/v1/containers/TXGU7408862/timeline"
  }
}
```

## Integration Notes

- `track` is idempotent for the same consumer, container number, and optional port.
- `track` returns `status_url` and `timeline_url` so clients do not need to rebuild paths.
- Start without `port_code` unless you need to override the route context manually.
- `current_status` is the strongest normalized lifecycle signal available.
- `timeline` is milestone-oriented and intentionally hides raw source-specific complexity.
- `summary` is the top-line card for dashboard or modal usage.
- `milestones` is the preferred customer-facing list.
- `journey_state` is the short phase field for list views and badges.
- webhooks should be treated as push notifications for the same normalized resources, not a second contract.
- Clients should integrate against the `v1` path structure now and only swap the host later when `api.cargoflowplus.com` goes live.
