Customs & CUSMA compliance

Getting Started

Base URL

https://cusmadocs.com/api/v1

Quick Start

  1. Create an API key in your API Keys settings
  2. Include the API key in your requests using the Authorization header
  3. Make your first API call to test the connection
  4. For mobile apps: Use the dedicated /api/v1/mobile/ endpoints for optimized performance

New: Mobile API Features

The API now includes dedicated mobile endpoints with:

  • Lightweight responses for faster loading
  • Automatic CORS support for web apps
  • Response compression to save mobile data
  • Intelligent rate limiting for protection
  • Offline sync capabilities

Authentication

Include your API key in the Authorization header or as a query parameter

Authorization Header

Authorization: Bearer YOUR_API_KEY

Query Parameter (Alternative)

?api_key=YOUR_API_KEY

Mobile Features

The CusmaDocs API is optimized for mobile app development with dedicated endpoints and features designed for mobile use cases.

Mobile-Optimized Endpoints

Dedicated /api/v1/mobile/ endpoints that return minimal data for faster loading and reduced bandwidth usage.

  • Lightweight certificate listings
  • Optimized dashboard summaries
  • Mobile file upload handling
  • Offline sync support

CORS Support

Full CORS headers support for mobile web applications and cross-origin requests.

  • Automatic preflight handling
  • Configurable origins
  • Standard HTTP methods
  • Custom headers support

Response Compression

Automatic gzip compression reduces data usage and improves mobile app performance.

  • Up to 70% size reduction
  • Automatic detection
  • Fallback support
  • Mobile data savings

Rate Limiting

Intelligent rate limiting protects the API while allowing normal mobile app usage patterns.

  • Per-endpoint limits
  • API key based tracking
  • Automatic cleanup
  • Graceful degradation

Mobile Endpoint Examples

Get Mobile Configuration

GET /api/v1/mobile/config
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "app_version": "1.0.0",
    "features": {
      "offline_sync": true,
      "push_notifications": true,
      "file_upload": true
    },
    "limits": {
      "max_file_size": 10485760,
      "supported_file_types": ["pdf", "jpg", "png", "doc"]
    }
  }
}

Mobile Dashboard Summary

GET /api/v1/mobile/dashboard
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "certificates": {
      "total": 15,
      "by_status": {"draft": 5, "signed": 8, "void": 2},
      "recent": [...]
    },
    "products": {"total": 25},
    "last_updated": "2024-01-15T10:30:00Z"
  }
}

Rate Limiting

The API implements intelligent rate limiting to ensure fair usage and protect against abuse while allowing normal mobile app operations.

Rate Limit Exceeded

When rate limits are exceeded, you'll receive a 429 status code:

HTTP/1.1 429 Too Many Requests { "success": false, "message": "Rate limit exceeded. Please try again later." }

Rate Limits by Endpoint

Endpoint Type Requests Time Window Examples
API Key Creation 10 15 minutes POST /api/v1/auth/keys
File Uploads 50 15 minutes POST /api/v1/mobile/upload
Data Listing 200 15 minutes GET /api/v1/mobile/certificates
General API 100 15 minutes All other endpoints

Best Practices

  • Cache responses when possible to reduce API calls
  • Batch requests instead of making many individual calls
  • Use pagination to limit data transfer
  • Implement retry logic with exponential backoff for 429 responses
  • Monitor usage to stay within limits

Authentication

GET /api/v1/auth/verify

Verify API key and get user information

Response

{ "success": true, "data": { "user": { "id": "user-uuid", "email": "user@example.com", "full_name": "John Doe" }, "account": { "id": "account-uuid", "name": "Company Name" } } }
GET /api/v1/auth/keys

List all API keys for the authenticated user

Response

{ "success": true, "data": [ { "id": "key-uuid", "name": "Production Server", "is_active": true, "expires_at": "2024-12-31T23:59:59Z", "last_used_at": "2024-01-15T10:30:00Z", "usage_count": 150, "created_at": "2024-01-01T00:00:00Z" } ] }
POST /api/v1/auth/keys

Create a new API key

Parameters

Name Type Required Description
name string Required Friendly name for the API key
expires_at datetime Optional Expiration date (ISO 8601 format)

Response

{ "success": true, "data": { "id": "key-uuid", "name": "Production Server", "key": "cusma_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "expires_at": "2024-12-31T23:59:59Z" }, "message": "IMPORTANT: Save this API key now. You will not be able to see it again." }
DELETE /api/v1/auth/keys/{key_id}

Revoke an API key

Parameters

Name Type Required Description
key_id string Required UUID of the API key to revoke

Response

{ "success": true, "message": "API key revoked successfully" }

Users

GET /api/v1/users/me

Get current user information

Response

{ "success": true, "data": { "id": "user-uuid", "email": "user@example.com", "full_name": "John Doe", "role": "Owner", "is_active": true, "created_at": "2024-01-01T00:00:00Z" } }
GET /api/v1/users

List all users in the account

Parameters

Name Type Required Description
page integer Optional Page number for pagination
limit integer Optional Number of users per page (max 100)

Response

{ "success": true, "data": [ { "id": "user-uuid", "email": "user@example.com", "full_name": "John Doe", "role": "Owner", "is_active": true, "last_login_at": "2024-01-15T10:30:00Z" } ], "pagination": { "current_page": 1, "total_pages": 1, "total_items": 5, "per_page": 20 } }

Products

GET /api/v1/products

List all products

Parameters

Name Type Required Description
page integer Optional Page number for pagination
limit integer Optional Number of products per page (max 100)
search string Optional Search products by name or description

Response

{ "success": true, "data": [ { "id": "product-uuid", "name": "Widget A", "description": "High-quality widget", "hs_code": "1234.56.78", "origin_country": "US", "created_at": "2024-01-01T00:00:00Z" } ], "pagination": { "current_page": 1, "total_pages": 1, "total_items": 10, "per_page": 20 } }
POST /api/v1/products

Create a new product

Parameters

Name Type Required Description
name string Required Product name
description string Optional Product description
hs_code string Required Harmonized System code
origin_country string Required Country of origin (ISO 3166-1 alpha-2)

Response

{ "success": true, "data": { "id": "product-uuid", "name": "Widget A", "description": "High-quality widget", "hs_code": "1234.56.78", "origin_country": "US", "created_at": "2024-01-01T00:00:00Z" }, "message": "Product created successfully" }

CUSMA Certificates

GET /api/v1/certificates

List all CUSMA certificates

Parameters

Name Type Required Description
page integer Optional Page number for pagination
limit integer Optional Number of certificates per page (max 100)
status string Optional Filter by status: draft, submitted, approved, rejected, voided

Response

{ "success": true, "data": [ { "id": "cert-uuid", "certificate_number": "CUSMA-2024-001", "status": "approved", "exporter_name": "Company Name", "importer_name": "Customer Name", "created_at": "2024-01-01T00:00:00Z" } ], "pagination": { "current_page": 1, "total_pages": 1, "total_items": 5, "per_page": 20 } }

Evidence Files

POST /api/v1/evidence

Upload evidence file for a certificate

Parameters

Name Type Required Description
certificate_id string Required UUID of the certificate
file file Required Evidence file (PDF, image, or document)
description string Optional Description of the evidence

Response

{ "success": true, "data": { "id": "file-uuid", "filename": "invoice.pdf", "size": 1024000, "mime_type": "application/pdf", "uploaded_at": "2024-01-01T00:00:00Z" }, "message": "Evidence file uploaded successfully" }

Mobile API

GET /api/v1/mobile/config

Get mobile app configuration and settings

Response

{ "success": true, "data": { "app_version": "1.0.0", "api_version": "1.0", "features": { "offline_sync": true, "push_notifications": true, "file_upload": true, "pdf_generation": true }, "limits": { "max_file_size": 10485760, "max_files_per_certificate": 20, "supported_file_types": [ "pdf", "jpg", "jpeg", "png", "doc", "docx", "xls", "xlsx", "txt" ] } } }
GET /api/v1/mobile/dashboard

Get dashboard summary optimized for mobile

Response

{ "success": true, "data": { "certificates": { "total": 15, "by_status": { "draft": 5, "signed": 8, "void": 2 }, "recent": [] }, "products": { "total": 25 }, "last_updated": "2024-01-15T10:30:00Z" } }
GET /api/v1/mobile/certificates

Get mobile-optimized certificate list with minimal data

Parameters

Name Type Required Description
page integer Optional Page number for pagination
per_page integer Optional Number of certificates per page (max 50)
status string Optional Filter by status
search string Optional Search certificates

Response

{ "success": true, "data": [ { "id": "cert-uuid", "cert_number": "CUSMA-2024-001", "status": "draft", "exporter_name": "Company Name", "importer_name": "Customer Name", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-15T10:30:00Z" } ], "pagination": { "current_page": 1, "total_pages": 1, "total_items": 5, "per_page": 20 } }
GET /api/v1/mobile/sync/status

Get sync status for offline support

Parameters

Name Type Required Description
last_sync datetime Optional Last sync timestamp (ISO 8601)

Response

{ "success": true, "data": { "has_changes": true, "changes": { "certificates": 3, "products": 1 }, "last_sync": "2024-01-15T09:00:00Z", "server_time": "2024-01-15T10:30:00Z" } }

HTTP Status Codes

Code Description Usage
200 Success Request completed successfully
201 Created Resource created successfully
400 Bad Request Invalid request parameters or missing required fields
401 Unauthorized Authentication required or invalid API key
403 Forbidden Insufficient permissions for this action
404 Not Found Resource not found
422 Unprocessable Entity Validation errors in request data
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Server error occurred

Code Examples

Curl

List Products

curl -X GET "https://cusmadocs.com/api/v1/products" \\n -H "Authorization: Bearer YOUR_API_KEY" \\n -H "Accept: application/json"

Create Product

curl -X POST "https://cusmadocs.com/api/v1/products" \\n -H "Authorization: Bearer YOUR_API_KEY" \\n -H "Content-Type: application/json" \\n -d '{"name": "Widget A", "hs_code": "1234.56.78", "origin_country": "US"}'

Upload Evidence

curl -X POST "https://cusmadocs.com/api/v1/evidence" \\n -H "Authorization: Bearer YOUR_API_KEY" \\n -F "certificate_id=uuid" \\n -F "file=@/path/to/evidence.pdf"

Mobile Config

curl -X GET "https://cusmadocs.com/api/v1/mobile/config" \\n -H "Authorization: Bearer YOUR_API_KEY" \\n -H "Accept: application/json"

Mobile Dashboard

curl -X GET "https://cusmadocs.com/api/v1/mobile/dashboard" \\n -H "Authorization: Bearer YOUR_API_KEY" \\n -H "Accept: application/json"

Mobile Upload

curl -X POST "https://cusmadocs.com/api/v1/mobile/upload" \\n -H "Authorization: Bearer YOUR_API_KEY" \\n -F "certificate_id=uuid" \\n -F "file=@/path/to/evidence.pdf" \\n -F "type=invoice"

Javascript

Fetch Products

const response = await fetch('/api/v1/products', {\n method: 'GET',\n headers: {\n 'Authorization': 'Bearer YOUR_API_KEY',\n 'Accept': 'application/json'\n }\n});\nconst data = await response.json();

Create Product

const response = await fetch('/api/v1/products', {\n method: 'POST',\n headers: {\n 'Authorization': 'Bearer YOUR_API_KEY',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n name: 'Widget A',\n hs_code: '1234.56.78',\n origin_country: 'US'\n })\n});

Mobile Config

const response = await fetch('/api/v1/mobile/config', {\n method: 'GET',\n headers: {\n 'Authorization': 'Bearer YOUR_API_KEY',\n 'Accept': 'application/json'\n }\n});\nconst config = await response.json();\nconsole.log('App features:', config.data.features);

Mobile Dashboard

const response = await fetch('/api/v1/mobile/dashboard', {\n method: 'GET',\n headers: {\n 'Authorization': 'Bearer YOUR_API_KEY',\n 'Accept': 'application/json'\n }\n});\nconst dashboard = await response.json();\nconsole.log('Total certificates:', dashboard.data.certificates.total);

Mobile Upload

const formData = new FormData();\nformData.append('file', fileInput.files[0]);\nformData.append('certificate_id', 'cert-uuid');\nformData.append('type', 'invoice');\n\nconst response = await fetch('/api/v1/mobile/upload', {\n method: 'POST',\n headers: {\n 'Authorization': 'Bearer YOUR_API_KEY'\n },\n body: formData\n});\nconst result = await response.json();

Php

List Products

$response = file_get_contents('https://cusmadocs.com/api/v1/products', false, stream_context_create([\n 'http' => [\n 'method' => 'GET',\n 'header' => 'Authorization: Bearer YOUR_API_KEY\r\nAccept: application/json'\n ]\n]));\n$data = json_decode($response, true);

Create Product

$data = [\n 'name' => 'Widget A',\n 'hs_code' => '1234.56.78',\n 'origin_country' => 'US'\n];\n\n$options = [\n 'http' => [\n 'method' => 'POST',\n 'header' => 'Authorization: Bearer YOUR_API_KEY\r\nContent-Type: application/json',\n 'content' => json_encode($data)\n ]\n];\n\n$response = file_get_contents('https://cusmadocs.com/api/v1/products', false, stream_context_create($options));

Mobile Config

$response = file_get_contents('https://cusmadocs.com/api/v1/mobile/config', false, stream_context_create([\n 'http' => [\n 'method' => 'GET',\n 'header' => 'Authorization: Bearer YOUR_API_KEY\r\nAccept: application/json'\n ]\n]));\n$config = json_decode($response, true);\necho "App features: " . json_encode($config['data']['features']);

Mobile Dashboard

$response = file_get_contents('https://cusmadocs.com/api/v1/mobile/dashboard', false, stream_context_create([\n 'http' => [\n 'method' => 'GET',\n 'header' => 'Authorization: Bearer YOUR_API_KEY\r\nAccept: application/json'\n ]\n]));\n$dashboard = json_decode($response, true);\necho "Total certificates: " . $dashboard['data']['certificates']['total'];