Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
1062d41
docs(openapi)!: document 204 deletes and shared error responses
dodeja Oct 14, 2026
0223e7d
docs(openapi)!: mark relationships and columns staging serves as null
dodeja Oct 14, 2026
dc423fb
docs(openapi)!: type port and metro area coordinates as decimal strings
dodeja Oct 14, 2026
ec6e737
docs(openapi): describe resource links and raw pagination links
dodeja Oct 14, 2026
4ab046f
docs(openapi)!: allow terminals, transport events, and raw events in …
dodeja Oct 14, 2026
71cf3d2
docs(openapi)!: document tracking request cancellation and ref_number…
dodeja Oct 14, 2026
c9a02f7
docs(openapi)!: add missing webhook events and default active to true
dodeja Oct 14, 2026
8ae1fa2
docs(openapi)!: document GET /search result type as search_result
dodeja Oct 14, 2026
971589f
docs(openapi)!: match the webhook notification examples response
dodeja Oct 14, 2026
1eb41ff
docs(openapi)!: document account custom field definitions and entity …
dodeja Oct 14, 2026
7549b83
docs(openapi)!: edit documents with document_type, not document_type_…
dodeja Oct 14, 2026
19393f7
docs(openapi)!: document 404 on every lookup by path parameter
dodeja Oct 14, 2026
3c90db5
docs(openapi): document the container edit attributes and errors
dodeja Oct 15, 2026
1afdc6f
docs(openapi)!: allow null pod_terminal data on containers
dodeja Oct 15, 2026
139d0e8
docs(openapi): give every nullable schema a type
dodeja Oct 15, 2026
ce7c3ab
docs(openapi)!: document the tracking request user relationship and a…
dodeja Oct 17, 2026
fed8e84
docs(openapi): document the user-provided MBL and booking numbers on …
dodeja Oct 17, 2026
aa1b4e5
docs(openapi)!: allow null shipment data on containers
dodeja Oct 17, 2026
b00a12f
docs(openapi)!: allow null entries in shipment ref_numbers
dodeja Oct 17, 2026
a725a85
chore: Auto-generate Postman collection from openapi.json [skip ci]
github-actions[bot] Oct 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17,200 changes: 12,694 additions & 4,506 deletions Terminal49-API.postman_collection.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
---
title: Create a custom field definition
description: "Create a new custom field definition in the Terminal49 API to attach structured metadata like reference codes or enums to shipments and containers."
og:title: Create a Custom Field Definition | Terminal49 API Documentation
og:description: Create a new custom field definition for shipments or containers in the Terminal49 API. Define the field name, data type, and api_slug for programmatic access.
title: Create a custom field definition template
description: "Create a Terminal49 custom field definition template. Only Terminal49 accounts can create templates; use the account-scoped route for your own definitions."
og:title: Create a Custom Field Definition Template | Terminal49 API Documentation
og:description: Create a Terminal49 custom field definition template. Other accounts receive 401 and should create definitions with the account-scoped route.
openapi: post /custom_field_definitions
---

Create a custom field definition to describe metadata you want to store on shipments or containers.
Creates a Terminal49 template definition. Only Terminal49 accounts can create templates; other accounts receive `401`. To create a definition on your account, use [Create an account custom field definition](/api-docs/api-reference/custom-fields/create-account-custom-field-definition).

## Request body

| Parameter | Required | Description |
|-----------|----------|-------------|
| `entity_type` | Yes | The entity type this field applies to (`Shipment` or `Container`) |
| `entity_type` | Yes | The entity type this field applies to: `Shipment` or `Cargo` (containers) |
| `api_slug` | Yes | Unique identifier for the field |
| `display_name` | Yes | Human-readable name for the field |
| `data_type` | Yes | Data type for values (for example: `short_text`, `number`, `date`, `reference`) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Use this endpoint to create a custom field value on a shipment or container when
| `data.type` | Yes | Must be `custom_field` |
| `data.attributes.api_slug` | Yes | The slug of the custom field definition |
| `data.attributes.value` | Yes | The field value (must match the definition's data type) |
| `data.relationships.entity.data.type` | Yes | `shipment` or `container` |
| `data.relationships.entity.data.id` | Yes | The shipment or container ID |
| `data.relationships.entity.data.type` | Yes | `shipment`, `container`, or `tracking_request` |
| `data.relationships.entity.data.id` | Yes | The shipment, container, or tracking request ID |

## Value formats by data type

Expand All @@ -36,7 +36,7 @@ Use this endpoint to create a custom field value on a shipment or container when
- Values are validated against the definition's data type
- Enum values must match one of the definition's configured options
- Reference values must match the definition's configured `reference_type`
- The `api_slug` must reference a definition belonging to your account or a Terminal49 template
- The `api_slug` must reference a definition belonging to your account; otherwise the request returns `404`

## Example request

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Create an account custom field definition
description: "Create a custom field definition on your Terminal49 account to attach structured metadata, like reference codes or enums, to shipments and containers."
og:title: Create an Account Custom Field Definition | Terminal49 API Documentation
og:description: Create a custom field definition on your Terminal49 account for shipments or containers. Define the display name, data type, and api_slug, or copy a template.
openapi: post /accounts/{account_id}/custom_field_definitions
---

Creates a custom field definition on your account. The API always creates the definition on the authenticated user's account, whatever `account_id` you pass.

## Request body

Send `template_id`, or all of `entity_type`, `api_slug`, `display_name` and `data_type`.

| Parameter | Required | Description |
|-----------|----------|-------------|
| `entity_type` | Without `template_id` | The entity type this field applies to: `Shipment` or `Cargo` (containers). Other values return `422`. |
| `api_slug` | Without `template_id` | Unique identifier for the field |
| `display_name` | Without `template_id` | Human-readable name for the field |
| `data_type` | Without `template_id` | Data type for values (for example: `short_text`, `number`, `date`, `reference`) |
| `template_id` | No | ID of a Terminal49 template definition to copy. The template supplies `entity_type`, `api_slug`, `display_name`, `data_type` and the other attributes. Attributes you send override the template's values. An unknown `template_id` returns `404`. |
| `description` | No | Optional description of the field's purpose |
| `validation` | No | Validation rules (for example: `required`, `pattern`, `max_length`) |
| `default_format` | No | Default format string for numbers or dates |
| `default_value` | No | Default value for new custom fields |
| `reference_type` | No | Required when `data_type` is `reference` |
| `reference_number` | No | Whether values are reference numbers. Terminal49 indexes reference-number values for global search and document matching. Defaults to `false`. |
| `sensitive` | No | Whether the field is sensitive. Sensitive fields are hidden from recipients of externally shared container views. Defaults to `false`. |
| `inline_option_creation` | No | Whether users can add a new option while entering an `enum` or `enum_multi` value in the Terminal49 app. Defaults to `false`. |
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: Delete a custom field definition
description: "Delete a custom field definition from your Terminal49 account, removing the field type and its applied values from shipments and containers permanently."
description: "Delete a custom field definition from your Terminal49 account. A definition that already has values cannot be deleted; archive it instead."
og:title: Delete a Custom Field Definition | Terminal49 API Documentation
og:description: Delete a custom field definition from the Terminal49 API. Removes the field schema and all associated values from every shipment and container record.
og:description: Delete a custom field definition from the Terminal49 API. Returns 204 on success, 422 when the definition has values, or 401 when a non-Terminal49 account deletes a template.
openapi: delete /custom_field_definitions/{id}
---

Expand All @@ -16,4 +16,8 @@ Delete a custom field definition by its ID.

## Behavior

Deleting a custom field definition also removes all associated custom field values.
Returns `204` when the definition is deleted.

- A definition that has values returns `422` with the title `This field has data. You can archive it instead.`
- Templates are managed by Terminal49. Other accounts get `401` when they delete a template.
- For a Terminal49 account, a template that other accounts use returns `422` with the title `This template is in use by other accounts. You can archive it instead.`
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: List account custom field definitions
description: "List the custom field definitions configured for your Terminal49 account, including data type, api_slug, and the entity type each definition applies to."
og:title: List Account Custom Field Definitions | Terminal49 API Documentation
og:description: List the custom field definitions configured for your Terminal49 account. Returns display names, data types, api_slugs, and entity types for shipments and containers.
openapi: get /accounts/{account_id}/custom_field_definitions
---

Lists the custom field definitions configured for your account. The list is not paginated. The API ignores `page[number]` and `page[size]` and returns every row, but still sends pagination `links`. Do not follow `links.next`.

The API always returns the definitions of the authenticated user's account, whatever `account_id` you pass.

## Query filters

| Filter | Description |
|--------|-------------|
| `filter[entity_type]` | Filter by entity type: `Shipment` or `Cargo` (containers) |
| `filter[data_type]` | Filter by data type |
| `filter[display_name]` | Filter by display name (prefix match) |
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
title: List custom field definitions
description: "List every custom field definition configured for your Terminal49 account, including data type, slug, and the target resource each definition applies to."
og:title: List Custom Field Definitions | Terminal49 API Documentation
og:description: List all custom field definitions configured for shipments and containers in the Terminal49 API. Returns field names, types, api_slugs, and resource scopes.
title: List custom field definition templates
description: "List the Terminal49 custom field definition templates. To list the definitions configured for your account, use the account-scoped route."
og:title: List Custom Field Definition Templates | Terminal49 API Documentation
og:description: List the Terminal49 custom field definition templates. Copy a template into your account with the template_id attribute of the account create route.
openapi: get /custom_field_definitions
---

List all custom field definitions available to your account.
Lists the Terminal49 template definitions. It does not return the definitions configured for your account. To list those, use [List account custom field definitions](/api-docs/api-reference/custom-fields/list-account-custom-field-definitions).

## Query filters

| Filter | Description |
|--------|-------------|
| `filter[entity_type]` | Filter by entity type (`Shipment` or `Container`) |
| `filter[entity_type]` | Filter by entity type: `Shipment` or `Cargo` (containers) |
| `filter[data_type]` | Filter by data type |
| `filter[display_name]` | Filter by display name (prefix match) |
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ og:description: List all selectable options for an enum-type custom field defini
openapi: get /custom_field_definitions/{definition_id}/options
---

List all options for a custom field definition.
List all options for a custom field definition. The list is not paginated. The API ignores `page[number]` and `page[size]` and returns every row, but still sends pagination `links`. Do not follow `links.next`.

## Path parameters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Filter results using these query parameters:

| Filter | Description |
|--------|-------------|
| `filter[entity_type]` | Filter by entity type (`Shipment` or `Container`) |
| `filter[entity_id]` | Filter by the ID of the shipment or container |
| `filter[entity_type]` | Filter by entity type. The value must match exactly: `Shipment`, `Cargo` (containers), or `TrackingRequest` |
| `filter[entity_id]` | Filter by the ID of the shipment, container, or tracking request |
| `filter[definition_id]` | Filter by custom field definition ID |

## Response
Expand Down
2 changes: 1 addition & 1 deletion docs/api-docs/api-reference/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Some endpoints have their own rate-limit bucket. For example, Infer Tracking Num
## Supporting resources

<CardGroup cols={3}>
<Card title="Custom Fields" href="/api-docs/api-reference/custom-fields/list-custom-field-definitions">
<Card title="Custom Fields" href="/api-docs/api-reference/custom-fields/list-account-custom-field-definitions">
Attach your own metadata to shipments and containers.
</Card>
<Card title="Shipping Lines" href="/api-docs/api-reference/shipping-lines/shipping-lines">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ description: "Retrieve a single metro area from the Terminal49 API by metro area
og:title: Get Metro Area by UNLOCODE or ID | Terminal49 API
og:description: Retrieve detailed metro area information using the UNLOCODE or ID, enhancing geographic data management with Terminal49's API.
openapi: get /metro_areas/{id}
---
---

Pass a metro area ID or a UN/LOCODE. An unknown ID or UN/LOCODE returns status `200` with `data: null`, not `404`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "Cancel a tracking request"
description: "Cancel a pending or awaiting_manifest tracking request in the Terminal49 API so Terminal49 stops trying to find the shipment."
og:title: Cancel a Tracking Request | Terminal49 API
og:description: Cancel a tracking request that is still pending or awaiting_manifest. The request moves to status cancelled with failed_reason Cancelled by user.
openapi: patch /tracking_requests/{id}/cancel
---

Cancels a tracking request whose `status` is `pending` or `awaiting_manifest`. The request moves to `status` `cancelled`, and `failed_reason` becomes `Cancelled by user`.

- A request in any other status returns `422`. The `errors` value in that response is a string, not a JSON:API errors array.
- A request that belongs to another account also returns `422`, not `404`.
- An unknown tracking request ID currently returns a `500` server error, not `404`. This differs from other lookups by ID, which return `404`. A `401` comes only from authentication. It means your API token is missing or invalid, or your account may not use the API.
- A request that has already created a shipment cannot be cancelled. To stop tracking that shipment, use [Stop tracking a shipment](/api-docs/api-reference/shipments/stop-tracking-shipment).
- To find cancelled requests, filter the list with `filter[status]=cancelled`.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ openapi: post /tracking_requests

Use `initial_custom_fields` to stage custom field values at creation time, before the shipment and containers exist. Terminal49 applies `shipment` entries to the shipment and `containers` entries to their containers once the tracking request resolves.

Each `api_slug` must match an existing [custom field definition](/api-docs/api-reference/custom-fields/create-a-custom-field-definition) on your account — a `Shipment`-scoped definition for `shipment` entries, a `Container`-scoped definition for `containers` entries. Container entries without a `number` — or with `number` set to an empty string — are applied to every container on the shipment; include a non-empty `number` to target one specific container.
Each `api_slug` must match an existing [custom field definition](/api-docs/api-reference/custom-fields/create-account-custom-field-definition) on your account — a `Shipment`-scoped definition for `shipment` entries, a `Cargo`-scoped definition for `containers` entries. Container entries without a `number` — or with `number` set to an empty string — are applied to every container on the shipment; include a non-empty `number` to target one specific container.

```json
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ Temporary reasons can become permanent when the `status` changes to `failed`:

[Failed Reasons when tracking request through dashboard](https://help.terminal49.com/en/articles/6116676-what-happens-after-i-add-a-shipment-to-terminal49-recently-added-shipments#h_ac9b93504f)

## Cancelled

You can cancel a tracking request while its `status` is `pending` or `awaiting_manifest` with [Cancel a tracking request](/api-docs/api-reference/tracking-requests/cancel-a-tracking-request) (`PATCH /tracking_requests/{id}/cancel`). The `status` changes to `cancelled` and `failed_reason` is set to `Cancelled by user`. A request in any other status cannot be cancelled.

## Stopped

When a shipment is no longer being updated then the tracking request `status` is marked as `tracking_stopped`.
Expand All @@ -78,7 +82,7 @@ You can also stop tracking a shipment from the dashboard.
Tracking is stopped at the **shipment level**, not on the tracking request or on an individual container. Use [Stop tracking a shipment](/api-docs/api-reference/shipments/stop-tracking-shipment) (`PATCH /shipments/{id}/stop_tracking`).

- A tracking request initiates tracking and can create a shipment. Once the shipment exists, the shipment is the resource you manage.
- There is no `DELETE` or "stop" endpoint on the `tracking_requests` resource. The tracking request `status` reflects the request outcome (`pending`, `created`, `failed`, `tracking_stopped`); the shipment is where active tracking is stopped or resumed.
- There is no `DELETE` or "stop" endpoint on the `tracking_requests` resource. Before a shipment exists, you can [cancel](#cancelled) the request instead. The tracking request `status` reflects the request outcome (`pending`, `awaiting_manifest`, `created`, `failed`, `cancelled`, `tracking_stopped`); the shipment is where active tracking is stopped or resumed.
- Stopping a shipment stops tracking for **all containers on that shipment**. There is no per-container stop endpoint. This behavior is the same whether the shipment was originally tracked by bill of lading, booking, or container number.
- To resume, use [Resume tracking a shipment](/api-docs/api-reference/shipments/resume-tracking-shipment).

Expand Down
30 changes: 0 additions & 30 deletions docs/api-docs/useful-info/webhook-events-examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4139,9 +4139,6 @@ Container is no longer available for pickup at the destination.
"data": []
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.transport.not_available"
}
}
```
Expand Down Expand Up @@ -4516,9 +4513,6 @@ Container was manually marked as delivered.
"data": []
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.transport.delivered"
}
}
```
Expand Down Expand Up @@ -6441,9 +6435,6 @@ Container arrived at the final inland destination.
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.transport.arrived_at_inland_destination"
},
"included": [
{
"id": "e7a78724-6ddd-48a2-85c9-e88def7a8406",
Expand Down Expand Up @@ -6782,9 +6773,6 @@ ETA changed for vessel departure at the port of lading.
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.transport.estimated.vessel_departed"
},
"included": [
{
"id": "3e1f544c-72a4-45d3-9cf0-14c892a63f34",
Expand Down Expand Up @@ -7014,9 +7002,6 @@ ETA changed for vessel arrival at the port of discharge (container level).
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.transport.estimated.vessel_arrived"
},
"included": [
{
"id": "e400b938-19d9-4d78-888f-351af48a915e",
Expand Down Expand Up @@ -7068,9 +7053,6 @@ ETA changed for the inland destination.
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.transport.estimated.arrived_at_inland_destination"
},
"included": [
{
"id": "a8d9896f-a483-4548-9bae-3107e6adca3b",
Expand Down Expand Up @@ -8248,9 +8230,6 @@ The coalesced `pickup_lfd` attribute changed. This field combines the `import_de
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.pickup_lfd.changed"
},
"included": [
{
"id": "29a59f1d-cd71-4c0c-9be8-bc453f945d27",
Expand Down Expand Up @@ -8584,9 +8563,6 @@ The terminal-reported Last Free Day (`import_deadlines.pickup_lfd_terminal`) at
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.pickup_lfd_terminal.changed"
},
"included": [
{
"id": "3b0adf2f-25b7-4dc8-bb98-8e43f804c3c7",
Expand Down Expand Up @@ -8638,9 +8614,6 @@ The rail-carrier-reported Last Free Day (`import_deadlines.pickup_lfd_rail`) at
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.pickup_lfd_rail.changed"
},
"included": [
{
"id": "5a62d9de-7ab6-49a5-87a8-b829286a2c5e",
Expand Down Expand Up @@ -8692,9 +8665,6 @@ The pickup appointment changed.
}
}
},
"links": {
"self": "https://api.terminal49.com/v2/webhook_notifications/examples?event=container.pickup_appointment.changed"
},
"included": [
{
"id": "6b9fc846-c244-4791-9ee4-f63d95620ec9",
Expand Down
Loading
Loading