ARK API
REST API for authorized ARK TMS scripts and integrations.
Developer portal | API docs for agents | OpenAPI 3.1 | MCP docs
API quickstart
The ARK API is in production preview. Access must be enabled for your organization, and an authorized ARK user must issue a restricted API token. The token is shown once. Store it in a secret manager or an environment variable, never in browser code or source control.
Base URL
https://arktms.com/api/v1
Make your first request
Set the token in your shell, then request the effective identity and access context:
export ARK_API_TOKEN="your-token"
curl https://arktms.com/api/v1/me \
-H "Authorization: Bearer $ARK_API_TOKEN"
A successful response includes ok: true, an API version, a request ID, and the connected actor's effective scopes, permissions, visible teams, and available operations. Keep the request ID when contacting support.
Check available operations
Use GET /api/v1/me before building a workflow. The result reflects the intersection of the current user, organization, team visibility, token restrictions, and rollout tier. A route documented here can still return missing_scope, missing_permission, or team_access_denied for a credential that lacks access.
The reference on this page contains the operations currently enabled for external access. Unavailable and internal operations are intentionally absent.
Authentication and scopes
REST API requests use an ARK API token in the standard bearer header:
Authorization: Bearer your-token
API tokens are for server-side scripts and integrations. Do not send an OAuth MCP access token to REST routes, and do not expose an API token in a browser, mobile application, prompt, or client-side bundle.
Effective access is always the intersection of:
current user permissions
AND organization membership
AND visible teams and entities
AND token scopes and restrictions
AND operation policy
AND enabled external-access tier
A scope never grants more access than the connected user already has. Team-limited tokens cannot reach records outside their configured teams. Token-specific row limits and rate limits can further reduce access.
Use the narrowest scopes required by the integration. The generated endpoint reference lists every required scope and ARK permission using canonical operation metadata.
Server- to- server automation
API tokens support dashboards, scheduled jobs, and other server-side integrations, but they are currently user-delegated credentials. A token is scoped to one organization and remains bound to its issuing user; it stops working if that user is deactivated or no longer belongs to the organization.
ARK does not currently issue organization service principals or OAuth client-credentials grants. Use a restricted API token with a durable owner for current integrations. MCP OAuth remains user-delegated and is intended for interactive AI clients, not unattended server-to-server authentication.
API concepts
Responses and request IDs
Successful API calls use a versioned JSON envelope with ok, api_version, request_id, and data. Error responses use ok: false and a stable error code. Every response also returns X-ARK-Request-Id; log it with the request outcome.
Use error codes for control flow. Message text is for people and may become more specific without a version change.
Pagination
List and search endpoints that support pagination expose limit and cursor parameters in their generated reference. Pass the returned cursor to the next request. Do not construct, inspect, or persist assumptions about cursor internals.
Page sizes are also constrained by the API token's maxRowsPerRequest policy. A request above that credential cap is rejected instead of silently widening access.
Data boundaries
Published resource shapes are external API contracts, not copies of ARK database tables. The public OpenAPI document includes only components reachable from available operations and omits unused internal schemas.
GET /api/v1/carriers searches carrier records belonging to the authenticated organization, uses cursor pagination, and returns at most 100 rows per request before any lower token policy is applied. It does not provide a bulk export of the FMCSA source dataset. Carrier risk endpoints return curated, record-specific safety context through their documented response contracts.
Preview availability
The reference publishes the complete external preview contract so integrations can be designed and tested before general availability. Runtime access is still the intersection of organization enrollment, the credential's scopes, ARK permissions, and team visibility. Operations marked x-ark-access-tier: full in OpenAPI require expanded-preview enrollment; the core preview remains available to the initial cohort.
Idempotency
Every external mutation marked as idempotent in the reference requires an Idempotency-Key header:
Idempotency-Key: a-stable-key-for-this-exact-attempt
Keys may be at most 200 characters and cannot contain control characters. Reuse a key only when retrying the exact same operation and payload. Reusing it with different input returns idempotency_key_conflict. ARK stores terminal outcomes so a retry can return the original result without repeating the write.
REST writes execute directly after authentication, authorization, validation, and idempotency checks. The server-backed human approval workflow described in the MCP guide does not apply to API-token requests.
Rate limits
API tokens default to 600 requests per minute. API and MCP traffic also shares an organization budget that defaults to 3000 requests per minute. Organization or credential policy can set lower or higher limits.
Authenticated responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. A 429 rate_limit_exceeded response also includes Retry-After. Production limits are distributed across application instances.
Errors
Common stable codes include unauthorized, missing_scope, missing_permission, team_access_denied, validation_failed, not_found, conflict, idempotency_key_required, idempotency_key_conflict, rate_limit_exceeded, external_access_disabled, and operation_not_available.
Treat 401 as an invalid or expired credential, 403 as insufficient scope or access, 404 as an unavailable or invisible resource, 409 as a state or idempotency conflict, and 429 as a signal to wait for Retry-After before retrying.
Broker workflows
Available workflows use normal ARK permissions and team visibility.
Triage the work queue
Call GET /api/v1/work-queue to summarize operational work visible to the connected user. Follow returned identifiers with specific read endpoints instead of downloading broad record sets.
Find and inspect a load
Use GET /api/v1/loads to search by load number, reference, status, or team. Then call GET /api/v1/loads/{loadId} and related stop, dispatch-note, tracking, bid, or billing-readiness endpoints for the selected load.
Review a carrier before assignment
Search carriers, then call GET /api/v1/carriers/{carrierId}/risk-card. The risk card summarizes available safety, authority, insurance, identity, onboarding, and internal eligibility signals. It does not make the booking decision.
Create and cover a load
Resolve customer, team, and locations first. Create the load with POST /api/v1/loads, then assign a carrier with POST /api/v1/loads/{loadId}/assign-carrier. Each write needs its own idempotency key. Use the generated request field tables and examples below; required fields come directly from OpenAPI.
Record dispatch context
Use POST /api/v1/loads/{loadId}/dispatches/{dispatchId}/notes for broker-visible call, exception, and follow-up context. This is an idempotent write and requires a unique key for the exact note attempt.
API reference
Browse 279 external preview operations by resource. Each detail page is generated from the public OpenAPI contract.
Context
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/me | context:read |
| GET | /api/v1/me/preferences | notifications:read |
| PATCH | /api/v1/me/preferences | notifications:write |
| GET | /api/v1/teams | context:read |
| POST | /api/v1/teams | admin:write |
| PATCH | /api/v1/teams/{teamId} | admin:write |
| GET | /api/v1/users | people:read |
| DELETE | /api/v1/users/{userId} | admin:write |
| PATCH | /api/v1/users/{userId} | admin:write |
| GET | /api/v1/users/{userId}/backup-users | admin:read |
| PUT | /api/v1/users/{userId}/backup-users | admin:write |
| GET | /api/v1/users/{userId}/commission-settings | admin:read |
| PUT | /api/v1/users/{userId}/commission-settings | admin:write |
| GET | /api/v1/users/{userId}/permissions | admin:read |
| PUT | /api/v1/users/{userId}/permissions | admin:write |
| PUT | /api/v1/users/{userId}/teams | admin:write |
| POST | /api/v1/users/invite | admin:write |
Search
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/search | context:read |
Operations
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/work-queue | operations:read, loads:read |
People
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/people | people:read |
| POST | /api/v1/people | people:write |
| DELETE | /api/v1/people/{personId} | people:write |
| GET | /api/v1/people/{personId} | people:read |
| PATCH | /api/v1/people/{personId} | people:write |
| POST | /api/v1/people/drivers/{driverId}/invite-app | people:write |
| POST | /api/v1/people/import | people:write, carriers:read |
Locations
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/locations | locations:read |
| POST | /api/v1/locations | locations:write |
| DELETE | /api/v1/locations/{locationId} | locations:write |
| GET | /api/v1/locations/{locationId} | locations:read |
| PATCH | /api/v1/locations/{locationId} | locations:write |
| POST | /api/v1/locations/import | locations:write |
Customers
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/customers | customers:read |
| POST | /api/v1/customers | customers:write |
| DELETE | /api/v1/customers/{customerId} | customers:write |
| GET | /api/v1/customers/{customerId} | customers:read |
| PATCH | /api/v1/customers/{customerId} | customers:write |
| PUT | /api/v1/customers/{customerId}/billing-requirements | customers:write |
| PUT | /api/v1/customers/{customerId}/managers | customers:write |
| PUT | /api/v1/customers/{customerId}/project44 | customers:write |
| PUT | /api/v1/customers/{customerId}/teams | customers:write |
| POST | /api/v1/customers/import | customers:write |
Carriers
Factoring
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/factoring-companies | factoring:read |
| POST | /api/v1/factoring-companies | factoring:write |
| DELETE | /api/v1/factoring-companies/{factoringCompanyId} | factoring:write |
| PATCH | /api/v1/factoring-companies/{factoringCompanyId} | factoring:write |
| POST | /api/v1/factoring-companies/import | factoring:write |
Billing
Loads
Reports
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/reports/aging | reports:read |
| GET | /api/v1/reports/aging/details | reports:read |
| GET | /api/v1/reports/aging/summary | reports:read |
| GET | /api/v1/reports/cash-flow | reports:read |
| GET | /api/v1/reports/commissions | reports:read |
| GET | /api/v1/reports/loads | reports:read |
| GET | /api/v1/reports/revenue | reports:read |
Documentation
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/docs/search | docs:read |
Reference
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/openapi.json | None |
Agent Sessions
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/agent-sessions | agents:read |
| POST | /api/v1/agent-sessions | agents:write |
| POST | /api/v1/agent-sessions/{sessionId}/stop | agents:write |
Approvals
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/approvals | agents:read |
Audit
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/audit/events | audit:read |
| GET | /api/v1/audit/events/{eventId} | audit:read |
| GET | /api/v1/audit/exports | audit:export |
| POST | /api/v1/audit/exports | audit:export |
| GET | /api/v1/audit/exports/{exportId}/download-url | audit:export |
| GET | /api/v1/audit/facets | audit:read |
| GET | /api/v1/audit/groups/{groupId} | audit:read |
| GET | /api/v1/audit/timeline | audit:read |
Carrier Invites
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/carrier-invites | carriers:read |
| POST | /api/v1/carrier-invites | carriers:write |
| DELETE | /api/v1/carrier-invites/{inviteId} | carriers:write |
| POST | /api/v1/carrier-invites/{inviteId}/resend | carriers:write |
| POST | /api/v1/carrier-invites/preview | carriers:read |
Edi
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/edi/connections | edi:read |
| POST | /api/v1/edi/connections | edi:write |
| PATCH | /api/v1/edi/connections/{connectionId} | edi:write |
| GET | /api/v1/edi/tenders | edi:read |
| POST | /api/v1/edi/tenders/{tenderId}/build-load | edi:read, loads:write |
| POST | /api/v1/edi/tenders/{tenderId}/decision | edi:write |
| POST | /api/v1/edi/tenders/{tenderId}/status-update | edi:write |
| Method | Path | Scope |
|---|---|---|
| POST | /api/v1/email/custom | loads:write |
Integrations
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/integrations/{provider}/settings | admin:read |
| POST | /api/v1/integrations/{provider}/settings | admin:write |
| GET | /api/v1/integrations/active | context:read |
| GET | /api/v1/integrations/project44/settings | admin:read |
| PATCH | /api/v1/integrations/project44/settings | admin:write |
| POST | /api/v1/integrations/project44/test | admin:write |
| GET | /api/v1/integrations/quickbooks/carrier-mappings | billing:read |
| PATCH | /api/v1/integrations/quickbooks/carrier-mappings | billing:write |
| GET | /api/v1/integrations/quickbooks/customer-mappings | billing:read |
| PATCH | /api/v1/integrations/quickbooks/customer-mappings | billing:write |
| GET | /api/v1/integrations/quickbooks/reference-data | billing:read |
| PATCH | /api/v1/integrations/quickbooks/settings | billing:write |
| GET | /api/v1/integrations/quickbooks/status | billing:read |
| GET | /api/v1/integrations/quickbooks/sync-jobs | loads:read, billing:read |
| POST | /api/v1/integrations/quickbooks/sync-jobs | loads:read, billing:write |
| POST | /api/v1/integrations/quickbooks/sync-jobs/{jobId}/retry | loads:read, billing:write |
Load Board
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/load-board/dat/private-network-groups | loads:read |
| GET | /api/v1/load-board/postings | loads:read |
| POST | /api/v1/load-board/postings | loads:write |
| GET | /api/v1/load-board/postings/preview | loads:read |
| POST | /api/v1/load-board/postings/reconcile-preview | loads:write |
| GET | /api/v1/load-board/provider-setup | loads:read |
| POST | /api/v1/load-board/user-connection | loads:write |
| GET | /api/v1/load-board/user-mappings | admin:read |
| PATCH | /api/v1/load-board/user-mappings | admin:write |
Notifications
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/notifications | notifications:read |
| POST | /api/v1/notifications/{notificationId}/read | notifications:write |
| POST | /api/v1/notifications/read-all | notifications:write |
Organization
| Method | Path | Scope |
|---|---|---|
| POST | /api/v1/organization/logos/finalize-upload | admin:write |
| POST | /api/v1/organization/logos/prepare-upload | admin:write |
| GET | /api/v1/organization/settings | admin:read |
| PATCH | /api/v1/organization/settings | admin:write |
Spot Quotes
Tracking
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/tracking/internal/availability | loads:dispatch |
| GET | /api/v1/tracking/internal/session-metrics | billing:read |
| GET | /api/v1/tracking/internal/usage-summary | billing:read |