API Documentation
Complete reference for integrating with the CusmaDocs API
Getting Started
Base URL
https://cusmadocs.com/api/v1
Quick Start
- Create an API key in your API Keys settings
- Include the API key in your requests using the Authorization header
- Make your first API call to test the connection
- 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
/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"
}
}
}
/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"
}
]
}
/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."
}
/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
/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"
}
}
/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
/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
}
}
/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
/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
/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
/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"
]
}
}
}
/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"
}
}
/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
}
}
/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'];