{"openapi":"3.1.0","info":{"title":"Wove External API","version":"1.0.0","description":"# Wove External API Documentation\n\nThe Wove External API allows you to programmatically access document processing, shipment management, and validation capabilities.\n\n## Features\n\n- **OAuth 2.0 Authentication**: Secure client credentials flow\n- **Rate Limiting**: Configurable per-client rate limits\n- **Document Processing**: Upload, validate, and merge shipping documents\n- **Shipment Management**: Create and manage shipment records with validation and merge operations\n- **Webhooks**: Get notified of document processing events (extraction, validation, merge)\n- **Comprehensive Error Handling**: Detailed error responses with troubleshooting information\n\n## Getting Started\n\n1. **Create OAuth Client**: Contact your account manager to create OAuth credentials\n2. **Get Access Token**: Use client credentials flow to obtain bearer token\n3. **Make API Calls**: Include bearer token in Authorization header\n4. **Handle Rate Limits**: Monitor rate limit headers in responses\n\n## Authentication\n\nAll API endpoints require OAuth 2.0 authentication using the client credentials flow.\n\n### Getting an Access Token\n\n```bash\ncurl -X POST https://api.wove.com/api/v1/external/auth/token \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"grant_type\": \"client_credentials\",\n    \"client_id\": \"your_client_id\",\n    \"client_secret\": \"your_client_secret\"\n  }'\n```\n\n### Using the Access Token\n\nInclude the access token in the Authorization header:\n\n```bash\ncurl -H \"Authorization: Bearer your_access_token\" \\\n  https://api.wove.com/api/v1/external/shipments\n```\n\n## Rate Limiting\n\nAll endpoints are subject to rate limiting based on your OAuth client configuration:\n\n- **Per-minute limit**: Default 60 requests/minute\n- **Daily limit**: Default 10,000 requests/day\n\nRate limit information is included in response headers:\n- `X-RateLimit-Limit-Minute`: Your per-minute limit\n- `X-RateLimit-Remaining-Minute`: Remaining requests this minute\n- `X-RateLimit-Reset-Minute`: When the minute window resets\n- `X-RateLimit-Limit-Day`: Your daily limit\n- `X-RateLimit-Remaining-Day`: Remaining requests today\n- `X-RateLimit-Reset-Day`: When the daily window resets\n\n## Webhook Security\n\nAll webhook payloads are signed using HMAC-SHA256 for verification:\n\n```javascript\n// Verify webhook signature\nconst crypto = require('crypto');\nconst signature = request.headers['x-wove-signature'];\nconst payload = JSON.stringify(request.body);\nconst expectedSignature = crypto\n  .createHmac('sha256', your_webhook_secret)\n  .update(payload)\n  .digest('hex');\n\nconst isValid = crypto.timingSafeEqual(\n  Buffer.from(signature),\n  Buffer.from(expectedSignature)\n);\n```\n\nHeaders included with every webhook:\n- `X-Wove-Signature`: HMAC-SHA256 signature of the payload\n- `X-Wove-Event`: Event type (e.g., \"extraction.completed\")\n- `X-Wove-Timestamp`: ISO timestamp when the webhook was sent\n\n## Error Handling\n\nAll errors follow a consistent format:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"VALIDATION_ERROR\",\n    \"message\": \"One or more documents not found or access denied\",\n    \"details\": {\n      \"field\": \"documentIds\",\n      \"value\": [\"invalid_id\"]\n    }\n  }\n}\n```\n\n### Error Codes\n\n- `VALIDATION_ERROR` - Invalid request parameters or data validation failure\n- `AUTHENTICATION_ERROR` - Invalid or expired credentials\n- `AUTHORIZATION_ERROR` - Insufficient permissions for the requested operation\n- `NOT_FOUND` - Requested resource not found\n- `RATE_LIMIT_ERROR` - Too many requests, rate limit exceeded\n- `INTERNAL_ERROR` - Internal server error\n\nSee the common error responses in the components section for detailed examples.\n","contact":{"name":"Wove API Support","email":"api-support@wove.com","url":"https://docs.wove.com"},"license":{"name":"Proprietary","url":"https://wove.com/terms"}},"servers":[{"url":"https://api.wove.com","description":"Production server"},{"url":"https://staging-api.wove.com","description":"Staging server"},{"url":"http://localhost:4000","description":"Development server"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"OAuth 2.0 Bearer token obtained from /auth/token endpoint"}},"schemas":{"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","description":"Response data (varies by endpoint)"},"message":{"type":"string","description":"Optional success message"}},"required":["success","data"]},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid input parameters"},"details":{"type":"object","description":"Additional error context"}}}},"required":["success","error"]},"PaginatedResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","description":"Array of items (varies by endpoint)"}},"message":{"type":"string","description":"Optional success message"},"pagination":{"type":"object","properties":{"page":{"type":"integer","example":1},"limit":{"type":"integer","example":20},"total":{"type":"integer","example":150},"totalPages":{"type":"integer","example":8},"hasNext":{"type":"boolean","example":true},"hasPrev":{"type":"boolean","example":false}},"required":["page","limit","total","totalPages","hasNext","hasPrev"]}},"required":["success","data","pagination"]},"TokenRequest":{"type":"object","properties":{"grant_type":{"type":"string","enum":["client_credentials"],"example":"client_credentials"},"client_id":{"type":"string","example":"wove_prod_abc123..."},"client_secret":{"type":"string","example":"sk_..."},"scope":{"type":"string","description":"Space-separated list of scopes. Available scopes include shipments:read, shipments:write,\ncustoms:read, customs:write, documents:read, documents:write and documents:delete.\n","example":"shipments:read documents:read validation:create"}},"required":["grant_type","client_id","client_secret"]},"TokenResponse":{"type":"object","properties":{"access_token":{"type":"string","example":"eyJhbGciOiJIUzI1NiIs..."},"token_type":{"type":"string","example":"Bearer"},"expires_in":{"type":"integer","example":3600,"description":"Token lifetime in seconds"},"scope":{"type":"string","example":"shipments:read documents:read validation:create"}}},"PortLocation":{"type":"object","properties":{"portCode":{"type":"string","example":"USLAX"},"portName":{"type":"string","example":"Los Angeles"},"countryCode":{"type":"string","example":"US"}},"required":["portCode"]},"AirportLocation":{"type":"object","properties":{"airportCode":{"type":"string","example":"LAX"},"airportName":{"type":"string","example":"Los Angeles International Airport"},"countryCode":{"type":"string","example":"US"}},"required":["airportCode"]},"AddressLocation":{"type":"object","properties":{"address1":{"type":"string","example":"123 Main St"},"address2":{"type":"string","example":"Suite 100"},"city":{"type":"string","example":"New York"},"province":{"type":"string","example":"NY"},"postalCode":{"type":"string","example":"10001"},"country":{"type":"string","example":"US"}}},"Location":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["Port"]},"portCode":{"type":"string","example":"USNYC"},"portName":{"type":"string","example":"New York/Newark"},"countryCode":{"type":"string","example":"US"}},"required":["type","portCode"]},{"type":"object","properties":{"type":{"type":"string","enum":["Airport"]},"airportCode":{"type":"string","example":"JFK"},"airportName":{"type":"string","example":"John F. Kennedy International Airport"},"countryCode":{"type":"string","example":"US"}},"required":["type","airportCode"]},{"type":"object","properties":{"type":{"type":"string","enum":["Door"]},"address1":{"type":"string","example":"123 Main St"},"address2":{"type":"string","example":"Suite 100"},"city":{"type":"string","example":"New York"},"province":{"type":"string","example":"NY"},"postalCode":{"type":"string","example":"10001"},"country":{"type":"string","example":"US"}},"required":["type","address1","city","country"]}]},"ReferenceNumber":{"type":"object","properties":{"id":{"type":"string","example":"1014810279825727493"},"type":{"type":"string","example":"booking","description":"Type of reference number (booking, invoice, po, etc.)"},"displayNumber":{"type":"string","example":"BOOK-2024-001"},"cleanedNumber":{"type":"string","example":"BOOK2024001","description":"Cleaned version without special characters"}},"required":["id","type","displayNumber"]},"ShipmentSummary":{"type":"object","properties":{"id":{"type":"string","example":"1014810279825727490"},"status":{"type":"string","enum":["draft","pending","booked","in_transit","delivered","cancelled"],"example":"draft","description":"Current status of the shipment"},"name":{"type":"string","example":"External API Test Shipment"},"shipmentType":{"type":"string","enum":["FCL","LCL","AIR","LTL","FTL","RAIL"],"example":"LCL"},"commodity":{"type":"string","example":"Electronics"},"portOfLoading":{"$ref":"#/components/schemas/PortLocation"},"portOfDischarge":{"$ref":"#/components/schemas/PortLocation"},"placeOfReceiptType":{"type":"string","enum":["Port","Airport","Door"]},"placeOfReceiptPort":{"$ref":"#/components/schemas/PortLocation"},"placeOfReceiptAirport":{"$ref":"#/components/schemas/AirportLocation"},"placeOfReceiptAddress":{"$ref":"#/components/schemas/AddressLocation"},"placeOfDeliveryType":{"type":"string","enum":["Port","Airport","Door"]},"placeOfDeliveryPort":{"$ref":"#/components/schemas/PortLocation"},"placeOfDeliveryAirport":{"$ref":"#/components/schemas/AirportLocation"},"placeOfDeliveryAddress":{"$ref":"#/components/schemas/AddressLocation"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"documentCount":{"type":"integer","example":5,"description":"Number of documents attached to this shipment"}}},"ShipmentCarrier":{"type":"object","properties":{"code":{"type":"string","example":"MAEU"},"name":{"type":"string","example":"Maersk Line"}},"required":["code","name"]},"Carrier":{"$ref":"#/components/schemas/ShipmentCarrier"},"ShipmentDetails":{"allOf":[{"$ref":"#/components/schemas/ShipmentSummary"},{"type":"object","properties":{"carrier":{"$ref":"#/components/schemas/Carrier"},"vessel":{"type":"string","example":"MSC OSCAR"},"voyage":{"type":"string","example":"123W"},"incoterm":{"type":"string","example":"FOB"},"serviceType":{"type":"string","example":"CY-CY"},"invoiceDate":{"type":"string","format":"date-time"},"dueDate":{"type":"string","format":"date-time"},"issueDate":{"type":"string","format":"date-time"},"shipmentDate":{"type":"string","format":"date-time"},"expectedDeliveryDate":{"type":"string","format":"date-time"},"readyDate":{"type":"string","format":"date-time"},"dateOfSignature":{"type":"string","format":"date-time"},"referenceNumbers":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceNumber"}},"consigneeName":{"$ref":"#/components/schemas/Organization"},"consigneeAddress":{"$ref":"#/components/schemas/Address"},"consigneeContactName":{"type":"string","nullable":true},"consigneeContactPhone":{"type":"string","nullable":true},"consigneeContactEmail":{"type":"string","nullable":true},"consignorName":{"$ref":"#/components/schemas/Organization"},"consignorAddress":{"$ref":"#/components/schemas/Address"},"consignorContactName":{"type":"string","nullable":true},"consignorContactPhone":{"type":"string","nullable":true},"consignorContactEmail":{"type":"string","nullable":true},"notifyPartyName":{"$ref":"#/components/schemas/Organization"},"notifyPartyAddress":{"$ref":"#/components/schemas/Address"},"notifyPartyContactName":{"type":"string","nullable":true},"notifyPartyContactPhone":{"type":"string","nullable":true},"notifyPartyContactEmail":{"type":"string","nullable":true},"destinationAgentName":{"$ref":"#/components/schemas/Organization"},"destinationAgentAddress":{"$ref":"#/components/schemas/Address"},"destinationAgentContactName":{"type":"string","nullable":true},"destinationAgentContactPhone":{"type":"string","nullable":true},"destinationAgentContactEmail":{"type":"string","nullable":true},"totalWeight":{"type":"number","nullable":true},"weightUnit":{"type":"string","nullable":true},"totalVolume":{"type":"number","nullable":true},"volumeUnit":{"type":"string","nullable":true},"totalPieces":{"type":"number","nullable":true},"totalPacks":{"type":"number","nullable":true},"totalPacksPackageType":{"type":"string","nullable":true},"totalValue":{"type":"number","nullable":true},"currency":{"type":"string","nullable":true}}}]},"ShipmentItem":{"type":"object","properties":{"id":{"type":"string","example":"1014810279825727491"},"lineNumber":{"type":"integer","example":1},"sku":{"type":"string","example":"SKU-12345"},"partNumber":{"type":"string","example":"PN-67890"},"description":{"type":"string","example":"Electronic Component"},"quantity":{"type":"number","example":100},"unitOfMeasure":{"type":"string","example":"PCS"},"unitPrice":{"type":"number","example":25.5},"amount":{"type":"number","example":2550},"currency":{"type":"string","example":"USD"},"countryOfOrigin":{"type":"string","example":"CN"},"hsCode":{"type":"string","example":"8541.10.00"},"weight":{"type":"number","example":150.5},"weightUnit":{"type":"string","example":"KG"},"volume":{"type":"number","example":2.5},"volumeUnit":{"type":"string","example":"CBM"},"packageNumber":{"type":"string","example":"PKG-001"},"dimensions":{"type":"object","properties":{"length":{"type":"number","example":100},"width":{"type":"number","example":50},"height":{"type":"number","example":50},"unit":{"type":"string","example":"CM"}}}}},"ShipmentContainer":{"type":"object","properties":{"id":{"type":"string","example":"1014810279825727492"},"number":{"type":"string","example":"MSKU1234567"},"size":{"type":"string","example":"40"},"type":{"type":"string","example":"HC"},"sizeType":{"type":"string","example":"40HC","description":"Combined size and type (e.g., 20GP, 40HC)"},"sealNumber":{"type":"string","example":"SEAL123456"},"quantity":{"type":"integer","example":1},"packages":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentPackage"},"description":"Packages contained in this container"}}},"Container":{"$ref":"#/components/schemas/ShipmentContainer"},"ShipmentPackage":{"type":"object","properties":{"id":{"type":"string","example":"1014810279825727493"},"containerId":{"type":"string","nullable":true,"description":"ID of the container this package belongs to (null for loose packages)"},"packageNumber":{"type":"string","example":"PKG001"},"packageType":{"type":"string","example":"CARTON"},"description":{"type":"string","nullable":true},"packageCount":{"type":"integer","example":1},"lineNumber":{"type":"integer","nullable":true},"grossWeight":{"type":"number","nullable":true},"netWeight":{"type":"number","nullable":true},"volume":{"type":"number","nullable":true},"weightUnit":{"type":"string","nullable":true},"volumeUnit":{"type":"string","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentItem"},"description":"Items contained in this package"}}},"ShipmentEvent":{"type":"object","properties":{"id":{"type":"string","example":"1014810279825727495"},"eventType":{"type":"string","example":"status_change"},"eventDate":{"type":"string","format":"date-time"},"eventLocation":{"type":"string","example":"USLAX"},"eventDescription":{"type":"string","example":"Status changed from draft to booked"},"createdAt":{"type":"string","format":"date-time"}}},"CreateShipmentRequest":{"type":"object","properties":{"name":{"type":"string","example":"My Shipment"},"shipmentType":{"type":"string","enum":["FCL","LCL","AIR","LTL","FTL","RAIL"],"example":"FCL"},"commodity":{"type":"string","example":"Electronics"},"carrier":{"type":"string","example":"MSC"},"vessel":{"type":"string","example":"MSC OSCAR"},"voyage":{"type":"string","example":"123E"},"incoterm":{"type":"string","example":"FOB"},"serviceType":{"type":"string","example":"CY/CY"},"portOfLoading":{"type":"string","example":"CNSHA"},"portOfDischarge":{"type":"string","example":"USLAX"},"placeOfReceipt":{"$ref":"#/components/schemas/Location"},"placeOfDelivery":{"$ref":"#/components/schemas/Location"},"referenceNumbers":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceNumber"}},"customFields":{"type":"object","additionalProperties":true}},"required":["name"]},"UpdateShipmentRequest":{"allOf":[{"$ref":"#/components/schemas/CreateShipmentRequest"},{"type":"object","description":"All fields from CreateShipmentRequest are optional for updates"}]},"Document":{"type":"object","properties":{"id":{"type":"string","example":"1013737064058920960"},"entityId":{"type":"string","example":"1014810279825727490"},"entityType":{"type":"string","example":"shipment"},"type":{"type":"string","example":"CommercialInvoice"},"name":{"type":"string","example":"commercial_invoice.pdf"},"size":{"type":"integer","example":1024000},"checksum":{"type":"string","example":"a1b2c3d4e5f6..."},"isSelected":{"type":"boolean","example":true},"extractedData":{"type":"object","description":"Extracted data from the document","additionalProperties":true},"extractionStatus":{"type":"string","enum":["pending","processing","completed","failed"],"example":"completed"},"extractionError":{"type":"string","example":null},"extractedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ValidationRequest":{"type":"object","properties":{"documentIds":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":20,"example":["1013737064058920960","1013737064063115265"]},"ruleSetId":{"type":"string","description":"Optional validation rule set ID"},"async":{"type":"boolean","description":"Process validation asynchronously","default":false},"webhookUrl":{"type":"string","format":"uri","description":"Webhook URL for async processing notifications"}},"required":["documentIds"]},"ValidationJobResponse":{"type":"object","properties":{"jobId":{"type":"string","example":"1014851234567890123"},"status":{"type":"string","enum":["pending","processing","completed","failed"],"example":"pending"},"message":{"type":"string","example":"Validation job created. Use the job ID to check status."}}},"ValidationResult":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"result":{"type":"object","properties":{"status":{"type":"string","enum":["valid","warnings","errors"]},"issues":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning","info"]},"field":{"type":"string"},"message":{"type":"string"},"documents":{"type":"object","additionalProperties":true}}}}}}}},"MergeJobResponse":{"type":"object","properties":{"jobId":{"type":"string","example":"1014851234567890123"},"status":{"type":"string","enum":["pending","processing","completed","failed"],"example":"pending"},"documentIds":{"type":"array","items":{"type":"string"}},"message":{"type":"string","example":"Merge job created. Use the job ID to check status."}}},"MergeResult":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"result":{"type":"object","properties":{"mergedData":{"type":"object","additionalProperties":true},"conflicts":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"values":{"type":"object","additionalProperties":true},"resolution":{"type":"string"}}}}}}}},"Webhook":{"type":"object","properties":{"id":{"type":"string","example":"1014560123456789012"},"url":{"type":"string","format":"uri","example":"https://your-app.com/webhook"},"events":{"type":"array","items":{"type":"string","enum":["extraction.completed","extraction.failed","validation.completed","validation.failed","merge.completed","merge.failed","document.uploaded","document.deleted","shipment.created","shipment.updated","source.processing.completed","source.processing.failed","webhook.test"]}},"description":{"type":"string"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"lastTriggeredAt":{"type":"string","format":"date-time"}}},"CreateWebhookRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL to receive webhook notifications"},"events":{"type":"array","items":{"type":"string","enum":["extraction.completed","extraction.failed","validation.completed","validation.failed","merge.completed","merge.failed","document.uploaded","document.deleted","shipment.created","shipment.updated","source.processing.completed","source.processing.failed","webhook.test"]},"minItems":1},"description":{"type":"string"}},"required":["url","events"]},"WebhookPayload":{"type":"object","description":"Standard wrapper for all webhook payloads","properties":{"event":{"type":"string","description":"The event type that triggered this webhook","example":"extraction.completed"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was sent"},"data":{"type":"object","description":"Event-specific data payload"}},"required":["event","timestamp","data"]},"WebhookDocument":{"type":"object","description":"Document object included in webhook payloads","properties":{"id":{"type":"string","example":"1014560123456789012"},"type":{"type":"string","example":"CommercialInvoice"},"name":{"type":"string","example":"invoice_2024_001.pdf"},"size":{"type":"integer","example":245678},"checksum":{"type":"string","example":"1234567890123456"},"isSelected":{"type":"boolean"},"extractedData":{"type":"object","nullable":true,"description":"The extracted JSON data (null if not extracted)"},"extractionStatus":{"type":"string","enum":["pending","processing","completed","failed"]},"extractionError":{"type":"string","nullable":true},"extractedAt":{"type":"string","format":"date-time","nullable":true},"mimeType":{"type":"string","example":"application/pdf"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ExtractionCompletedPayload":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/WebhookDocument"},"entityType":{"type":"string","description":"Type of entity the document belongs to","example":"shipments"},"entityId":{"type":"string","description":"ID of the entity the document belongs to","example":"1014560123456789012"}}},"ExtractionFailedPayload":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/WebhookDocument"},"entityType":{"type":"string","example":"shipments"},"entityId":{"type":"string"},"error":{"type":"string","description":"Error message describing what went wrong"}}},"ValidationCompletedPayload":{"type":"object","properties":{"jobId":{"type":"string"},"entityId":{"type":"string","description":"ID of the entity being validated"},"entityType":{"type":"string","description":"Type of entity being validated","example":"shipments"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDocument"}},"validationResult":{"type":"object","description":"Validation results including any warnings/errors"},"itemsValidated":{"type":"integer"},"issuesFound":{"type":"integer"},"completedAt":{"type":"string","format":"date-time"},"type":{"type":"string","example":"cross-validation"}}},"ValidationFailedPayload":{"type":"object","properties":{"jobId":{"type":"string"},"entityId":{"type":"string"},"entityType":{"type":"string"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDocument"}},"error":{"type":"string"},"failedAt":{"type":"string","format":"date-time"},"type":{"type":"string","example":"cross-validation"}}},"MergeCompletedPayload":{"type":"object","properties":{"jobId":{"type":"string"},"entityId":{"type":"string"},"entityType":{"type":"string"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDocument"}},"mergeResult":{"type":"object","description":"Merged document data"},"completedAt":{"type":"string","format":"date-time"}}},"MergeFailedPayload":{"type":"object","properties":{"jobId":{"type":"string"},"entityId":{"type":"string"},"entityType":{"type":"string"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDocument"}},"error":{"type":"string"},"failedAt":{"type":"string","format":"date-time"}}},"DocumentUploadedPayload":{"type":"object","properties":{"documentId":{"type":"string"},"fileName":{"type":"string"},"entityId":{"type":"string","description":"ID of the parent entity"},"entityType":{"type":"string","description":"Type of parent entity (e.g., \"shipments\", \"rfq_shipments\")"},"shipmentName":{"type":"string","description":"Name of the associated shipment if applicable"},"uploadedAt":{"type":"string","format":"date-time"}}},"DocumentDeletedPayload":{"type":"object","properties":{"documentId":{"type":"string"},"fileName":{"type":"string"},"entityId":{"type":"string","description":"ID of the parent entity"},"entityType":{"type":"string","description":"Type of parent entity (e.g., \"shipments\", \"rfq_shipments\")"},"shipmentName":{"type":"string","description":"Name of the associated shipment if applicable"},"deletedAt":{"type":"string","format":"date-time"}}},"ShipmentCreatedPayload":{"type":"object","properties":{"shipmentId":{"type":"string"},"shipmentName":{"type":"string"},"shipmentType":{"type":"string"},"status":{"type":"string"},"commodity":{"type":"string","nullable":true},"portOfLoading":{"type":"string","nullable":true},"portOfDischarge":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"ShipmentUpdatedPayload":{"type":"object","properties":{"shipmentId":{"type":"string"},"shipmentName":{"type":"string"},"updates":{"type":"object","description":"Object containing the fields that were updated"},"previousData":{"type":"object","description":"Previous values of updated fields (optional)","nullable":true},"updatedAt":{"type":"string","format":"date-time"}}},"WebhookTestPayload":{"type":"object","properties":{"message":{"type":"string","example":"This is a test webhook from Wove API"},"customerId":{"type":"string"},"testId":{"type":"string","example":"test_1704067200000"}}},"DocumentHistoryEntry":{"type":"object","properties":{"type":{"type":"string","example":"edit"},"source":{"type":"string","example":"manual"},"date":{"type":"string","format":"date-time"},"changes":{"type":"object","additionalProperties":true}}},"ValidationIssue":{"type":"object","properties":{"field":{"type":"string","example":"portOfLoading"},"message":{"type":"string","example":"Port of loading is required for ocean shipments"},"severity":{"type":"string","example":"error"},"code":{"type":"string","example":"REQUIRED_FIELD"}}},"ValidationItem":{"type":"object","properties":{"id":{"type":"string","example":"1014810279825727496"},"crossValidationResultId":{"type":"string"},"shipmentId":{"type":"string"},"fieldName":{"type":"string","example":"invoiceNumber"},"status":{"type":"string","example":"error"},"reason":{"type":"string","example":"Invoice numbers do not match across documents"},"suggestion":{"type":"string","example":"Use invoice number from the commercial invoice"},"files":{"type":"array","items":{"type":"string"}},"documentIds":{"type":"array","items":{"type":"string"}},"actionStatus":{"type":"string","enum":["PENDING","ACCEPTED","IGNORED","OVERRIDDEN"]},"actionTakenById":{"type":"string"},"actionTakenAt":{"type":"string","format":"date-time"},"actionReason":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CrossValidationJob":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["cross-validation"]},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"progress":{"type":"number","description":"Progress percentage (0-100)"},"documentIds":{"type":"array","items":{"type":"string"}},"result":{"type":"object","nullable":true,"properties":{"validatedFields":{"type":"array","items":{"type":"string"}},"issues":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"},"severity":{"type":"string","enum":["critical","warning"]},"suggestion":{"type":"string","nullable":true},"files":{"type":"array","items":{"type":"string"}},"documents":{"type":"array","items":{"type":"string"}}}}},"validationResult":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"field":{"type":"string"},"files":{"type":"array","items":{"type":"string"}},"reason":{"type":"string"},"status":{"type":"string"},"suggestion":{"type":"string","nullable":true}}}}}},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time","nullable":true},"completedAt":{"type":"string","format":"date-time","nullable":true}}},"MergeJob":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["merge"]},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"progress":{"type":"number","description":"Progress percentage (0-100)"},"documentIds":{"type":"array","items":{"type":"string"}},"result":{"nullable":true},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time","nullable":true},"completedAt":{"type":"string","format":"date-time","nullable":true}}},"UpdateValidationItemRequest":{"type":"object","properties":{"actionStatus":{"type":"string","enum":["ACCEPTED","IGNORED","OVERRIDDEN"]},"actionReason":{"type":"string"}},"required":["actionStatus"]},"ValidateDocumentsRequest":{"type":"object","properties":{"documentIds":{"type":"array","items":{"type":"string"},"minItems":1}},"required":["documentIds"]},"MergeDocumentsRequest":{"type":"object","properties":{"documentIds":{"type":"array","items":{"type":"string"},"minItems":2}},"required":["documentIds"]},"UpdateShipmentDetailsRequest":{"type":"object","description":"Request body for updating shipment-level details only.\nContainers, packages, and items are now managed through separate CRUD endpoints.\n","properties":{"shipment":{"type":"object","properties":{"carrier":{"type":"string"},"vessel":{"type":"string"},"voyage":{"type":"string"},"incoterm":{"type":"string"},"serviceType":{"type":"string"},"invoiceDate":{"type":"string","example":"2024-03-15"},"dueDate":{"type":"string","example":"2024-04-15"},"issueDate":{"type":"string","example":"2024-03-10"},"shipmentDate":{"type":"string","example":"2024-03-20"},"expectedDeliveryDate":{"type":"string","example":"2024-04-05"},"readyDate":{"type":"string","example":"2024-03-18"},"dateOfSignature":{"type":"string","example":"2024-03-10"},"portOfLoading":{"type":"string"},"portOfDischarge":{"type":"string"},"placeOfReceiptType":{"type":"string","enum":["Port","Airport","Door"]},"placeOfReceiptPort":{"$ref":"#/components/schemas/PortLocation"},"placeOfReceiptAirport":{"$ref":"#/components/schemas/AirportLocation"},"placeOfReceiptAddress":{"$ref":"#/components/schemas/AddressLocation"},"placeOfDeliveryType":{"type":"string","enum":["Port","Airport","Door"]},"placeOfDeliveryPort":{"$ref":"#/components/schemas/PortLocation"},"placeOfDeliveryAirport":{"$ref":"#/components/schemas/AirportLocation"},"placeOfDeliveryAddress":{"$ref":"#/components/schemas/AddressLocation"},"referenceNumbers":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceNumber"}},"consigneeName":{"type":"string","description":"Consignee/receiver company name"},"consigneeAddress":{"type":"object","description":"Consignee address (JSON object)"},"consigneeContactName":{"type":"string","description":"Consignee contact person name"},"consigneeContactPhone":{"type":"string","description":"Consignee contact phone number"},"consigneeContactEmail":{"type":"string","format":"email","description":"Consignee contact email address"},"consignorName":{"type":"string","description":"Consignor company name"},"consignorAddress":{"type":"object","description":"Consignor address (JSON object)"},"consignorContactName":{"type":"string","description":"Consignor contact person name"},"consignorContactPhone":{"type":"string","description":"Consignor contact phone number"},"consignorContactEmail":{"type":"string","format":"email","description":"Consignor contact email address"},"notifyPartyName":{"type":"string","description":"Notify party company name"},"notifyPartyAddress":{"type":"object","description":"Notify party address (JSON object)"},"notifyPartyContactName":{"type":"string","description":"Notify party contact person name"},"notifyPartyContactPhone":{"type":"string","description":"Notify party contact phone number"},"notifyPartyContactEmail":{"type":"string","format":"email","description":"Notify party contact email address"},"destinationAgentName":{"type":"string","description":"Destination agent company name"},"destinationAgentAddress":{"type":"object","description":"Destination agent address (JSON object)"},"destinationAgentContactName":{"type":"string","description":"Destination agent contact person name"},"destinationAgentContactPhone":{"type":"string","description":"Destination agent contact phone number"},"destinationAgentContactEmail":{"type":"string","format":"email","description":"Destination agent contact email address"},"totalWeight":{"type":"number","nullable":true,"description":"Total weight of all packages","example":1500.5},"weightUnit":{"type":"string","nullable":true,"description":"Unit for weight measurements","example":"KG"},"totalVolume":{"type":"number","nullable":true,"description":"Total volume of all packages","example":25.5},"volumeUnit":{"type":"string","nullable":true,"description":"Unit for volume measurements","example":"CBM"},"totalPieces":{"type":"integer","nullable":true,"description":"Total number of pieces/items","example":500},"totalPacks":{"type":"integer","nullable":true,"description":"Total number of top-level shipping units (e.g., 7 pallets containing 200 cartons)","example":7},"totalPacksPackageType":{"type":"string","nullable":true,"description":"Type of shipping units for totalPacks (e.g., Pallets, Containers)","example":"Pallets"},"totalValue":{"type":"number","nullable":true,"description":"Total declared value of the shipment","example":25000},"currency":{"type":"string","nullable":true,"description":"Currency code for the total value (ISO 4217)","example":"USD"}}}}},"CreateContainerRequest":{"type":"object","required":["number","sizeType"],"properties":{"number":{"type":"string","description":"Container number/identifier","example":"MSKU1234567"},"sizeType":{"type":"string","description":"Container size and type (e.g., 20GP, 40HC)","example":"20GP"},"sealNumber":{"type":"string","description":"Container seal number"},"quantity":{"type":"integer","description":"Number of containers","default":1,"minimum":1}}},"UpdateContainerRequest":{"type":"object","properties":{"number":{"type":"string","description":"Container number/identifier"},"sizeType":{"type":"string","description":"Container size and type"},"sealNumber":{"type":"string","description":"Container seal number"},"quantity":{"type":"integer","description":"Number of containers","minimum":1}}},"CreatePackageRequest":{"type":"object","properties":{"containerId":{"type":"string","nullable":true,"description":"Container ID (null for loose packages)"},"packageNumber":{"type":"string","description":"Package number/identifier"},"packageType":{"type":"string","description":"Type of package (e.g., CARTON, PALLET)"},"description":{"type":"string","description":"Package description"},"packageCount":{"type":"integer","description":"Number of packages","minimum":1},"lineNumber":{"type":"integer","description":"Line number for ordering"},"grossWeight":{"type":"number","description":"Gross weight of package"},"netWeight":{"type":"number","description":"Net weight of package"},"volume":{"type":"number","description":"Volume of package"},"weightUnit":{"type":"string","description":"Unit for weight measurements"},"volumeUnit":{"type":"string","description":"Unit for volume measurements"}}},"UpdatePackageRequest":{"type":"object","properties":{"packageNumber":{"type":"string"},"packageType":{"type":"string"},"description":{"type":"string"},"packageCount":{"type":"integer","minimum":1},"lineNumber":{"type":"integer"},"grossWeight":{"type":"number"},"netWeight":{"type":"number"},"volume":{"type":"number"},"weightUnit":{"type":"string"},"volumeUnit":{"type":"string"}}},"CreateItemRequest":{"type":"object","properties":{"packageId":{"type":"string","nullable":true,"description":"Package ID this item belongs to"},"containerId":{"type":"string","nullable":true,"description":"Container ID (optional)"},"lineNumber":{"type":"integer","description":"Line number for ordering"},"sku":{"type":"string","description":"Stock Keeping Unit"},"partNumber":{"type":"string","description":"Part number"},"description":{"type":"string","description":"Item description"},"quantity":{"type":"integer","description":"Quantity of items","minimum":1},"unitOfMeasure":{"type":"string","description":"Unit of measure for quantity"},"unitPrice":{"type":"number","description":"Price per unit"},"amount":{"type":"number","description":"Total amount"},"currency":{"type":"string","description":"Currency code"},"countryOfOrigin":{"type":"string","description":"Country of origin code"},"hsCode":{"type":"string","description":"Harmonized System code"},"weight":{"type":"number","description":"Weight per item"},"weightUnit":{"type":"string","description":"Unit for weight measurement"}}},"UpdateItemRequest":{"type":"object","properties":{"lineNumber":{"type":"integer"},"sku":{"type":"string"},"partNumber":{"type":"string"},"description":{"type":"string"},"quantity":{"type":"integer","minimum":1},"unitOfMeasure":{"type":"string"},"unitPrice":{"type":"number"},"amount":{"type":"number"},"currency":{"type":"string"},"countryOfOrigin":{"type":"string"},"hsCode":{"type":"string"},"weight":{"type":"number"},"weightUnit":{"type":"string"}}},"CreateSourceUploadRequest":{"type":"object","properties":{"filename":{"type":"string","description":"The filename of the rate sheet to upload","example":"carrier_rates_2024.xlsx"},"contentType":{"type":"string","description":"MIME type of the file","example":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},"sourceType":{"type":"string","enum":["contract","spot","tariff"],"description":"Type of rate sheet"},"carrierId":{"type":"string","description":"Optional carrier ID to associate with this source"},"effectiveDate":{"type":"string","format":"date","description":"Date when rates become effective"},"expiryDate":{"type":"string","format":"date","description":"Date when rates expire"},"description":{"type":"string","description":"Optional description of the source"}},"required":["filename"]},"CreateSourceUploadResponse":{"type":"object","properties":{"sourceId":{"type":"string","description":"Unique identifier for the created source"},"uploadUrl":{"type":"string","description":"Presigned URL for uploading the file (expires in 15 minutes)"},"expiresAt":{"type":"string","format":"date-time","description":"When the upload URL expires"}},"required":["sourceId","uploadUrl","expiresAt"]},"ProcessSourceResponse":{"type":"object","properties":{"sourceId":{"type":"string","description":"The source ID"},"status":{"type":"string","enum":["pending","processing"],"description":"Current processing status"},"message":{"type":"string","description":"Status message"}},"required":["sourceId","status"]},"ExternalSourceSummary":{"type":"object","properties":{"id":{"type":"string","description":"Source ID"},"filename":{"type":"string","description":"Original filename"},"status":{"type":"string","enum":["awaiting_upload","pending","processing","complete","failed"],"description":"Processing status"},"sourceType":{"type":"string","enum":["contract","spot","tariff"]},"carrierId":{"type":"string"},"carrierName":{"type":"string"},"rateCount":{"type":"integer","description":"Number of rates extracted from this source"},"effectiveDate":{"type":"string","format":"date"},"expiryDate":{"type":"string","format":"date"},"createdAt":{"type":"string","format":"date-time"},"processedAt":{"type":"string","format":"date-time"}}},"ExternalSourceDetail":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"status":{"type":"string","enum":["awaiting_upload","pending","processing","complete","failed"]},"sourceType":{"type":"string","enum":["contract","spot","tariff"]},"carrierId":{"type":"string"},"carrierName":{"type":"string"},"rateCount":{"type":"integer"},"effectiveDate":{"type":"string","format":"date"},"expiryDate":{"type":"string","format":"date"},"description":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"processedAt":{"type":"string","format":"date-time"},"error":{"type":"string","nullable":true,"description":"Error message if processing failed"}}},"ExternalQueryBankSource":{"type":"object","properties":{"id":{"type":"string","description":"Query Bank entry ID"},"sourceId":{"type":"string","description":"The linked source ID"},"filename":{"type":"string","description":"Source filename"},"carrierId":{"type":"string"},"carrierName":{"type":"string"},"sourceType":{"type":"string"},"rateCount":{"type":"integer"},"effectiveDate":{"type":"string","format":"date"},"expiryDate":{"type":"string","format":"date"},"linkedAt":{"type":"string","format":"date-time","description":"When the source was added to Query Bank"}}},"AddSourceToQueryBankRequest":{"type":"object","properties":{"sourceId":{"type":"string","description":"The source ID to add to Query Bank"}},"required":["sourceId"]},"AddSourceToQueryBankResponse":{"type":"object","properties":{"sourceId":{"type":"string"},"linkedAt":{"type":"string","format":"date-time"}},"required":["sourceId","linkedAt"]},"RemoveSourceFromQueryBankResponse":{"type":"object","properties":{"sourceId":{"type":"string"},"unlinkedAt":{"type":"string","format":"date-time"}},"required":["sourceId","unlinkedAt"]},"QueryBankRateQueryRequest":{"type":"object","properties":{"origins":{"type":"array","items":{"type":"string"},"description":"Inland origin codes or region codes (USWC, USEC, etc.) for door moves","example":["USWC","USCHI"]},"destinations":{"type":"array","items":{"type":"string"},"description":"Inland destination codes or region codes for door moves","example":["CNSHA","CNNBO"]},"loadingPorts":{"type":"array","items":{"type":"string"},"description":"Port of loading codes (UN/LOCODE format)","example":["CNSHA","CNNBO"]},"dischargePorts":{"type":"array","items":{"type":"string"},"description":"Port of discharge codes (UN/LOCODE format)","example":["USLAX","USLGB"]},"effectiveDate":{"type":"string","format":"date","description":"Filter rates effective on or after this date"},"expiryDate":{"type":"string","format":"date","description":"Filter rates that haven't expired by this date"},"containerType":{"type":"string","enum":["dry","reefer","nor"],"description":"Container type filter"},"containerSizes":{"type":"array","items":{"type":"string","enum":["20ft","40ft","40ft_hc","45ft"]},"description":"Container size filter"},"carrierCodes":{"type":"array","items":{"type":"string"},"description":"Filter by specific carrier SCAC codes","example":["MAEU","MSCU","COSU"]},"commodityType":{"type":"string","description":"Filter by commodity type"},"limit":{"type":"integer","default":100,"maximum":500,"description":"Maximum number of rates to return"},"offset":{"type":"integer","default":0,"description":"Number of rates to skip for pagination"}}},"QueryBankRateQueryResponse":{"type":"object","properties":{"rates":{"type":"array","items":{"$ref":"#/components/schemas/CombinedRate"}},"metadata":{"type":"object","properties":{"totalRates":{"type":"integer","description":"Total number of matching rates"},"sourcesSearched":{"type":"integer","description":"Number of sources searched"},"queryTimeMs":{"type":"integer","description":"Query execution time in milliseconds"}}}}},"CombinedRate":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the rate (hash for deduplication)"},"placeOfReceipt":{"description":"Origin inland point (for pre-carriage)","allOf":[{"$ref":"#/components/schemas/LocationInfo"}]},"portOfLoading":{"description":"Port of loading","allOf":[{"$ref":"#/components/schemas/LocationInfo"}]},"portOfDischarge":{"description":"Port of discharge","allOf":[{"$ref":"#/components/schemas/LocationInfo"}]},"placeOfDelivery":{"description":"Destination inland point (for on-carriage)","allOf":[{"$ref":"#/components/schemas/LocationInfo"}]},"viaPorts":{"description":"Transshipment ports in order","type":"array","items":{"$ref":"#/components/schemas/LocationInfo"}},"carrierCode":{"type":"string","description":"Carrier SCAC code"},"carrierName":{"type":"string","description":"Carrier display name"},"effectiveDate":{"type":"string","format":"date"},"expiryDate":{"type":"string","format":"date"},"commodityType":{"type":"string"},"transitTime":{"type":"integer","description":"Transit time in days"},"legs":{"description":"Rate breakdown by leg (pre-carriage, main, on-carriage)","type":"array","items":{"$ref":"#/components/schemas/RateLeg"}},"containerRates":{"description":"Container-specific pricing","type":"array","items":{"$ref":"#/components/schemas/CombinedContainerRate"}},"surcharges":{"description":"Applicable surcharges","type":"array","items":{"$ref":"#/components/schemas/RateSurcharge"}},"sourceId":{"type":"string","description":"Source ID where this rate originated"},"sourceName":{"type":"string","description":"Source filename"}},"required":["id","portOfLoading","portOfDischarge","carrierCode","containerRates","sourceId","sourceName"]},"LocationInfo":{"type":"object","properties":{"code":{"type":"string","description":"Location code (UN/LOCODE for ports)","example":"CNSHA"},"name":{"type":"string","description":"Location display name","example":"Shanghai"},"type":{"type":"string","enum":["port","city","address","region"],"description":"Type of location"}},"required":["code","type"]},"RateLeg":{"type":"object","properties":{"type":{"type":"string","enum":["pre_carriage","main","on_carriage"],"description":"Leg type"},"origin":{"$ref":"#/components/schemas/LocationInfo"},"destination":{"$ref":"#/components/schemas/LocationInfo"},"mode":{"type":"string","enum":["truck","rail","barge","ocean"],"description":"Transport mode for this leg"},"rates":{"description":"Container rates for this specific leg","type":"array","items":{"$ref":"#/components/schemas/LegContainerRate"}}},"required":["type","origin","destination"]},"LegContainerRate":{"type":"object","properties":{"containerSize":{"type":"string","enum":["20ft","40ft","40ft_hc","45ft"]},"containerType":{"type":"string","enum":["dry","reefer","nor","general"]},"amount":{"type":"number","description":"Rate amount"},"currency":{"type":"string","description":"Currency code (ISO 4217)","example":"USD"}},"required":["containerSize","containerType","amount","currency"]},"CombinedContainerRate":{"type":"object","properties":{"containerType":{"type":"string","enum":["dry","reefer","nor"]},"containerSize":{"type":"string","enum":["20ft","40ft","40ft_hc","45ft"]},"amount":{"type":"number","description":"Total combined rate amount"},"currency":{"type":"string","example":"USD"},"breakdown":{"type":"object","properties":{"preCarriage":{"type":"number","description":"Pre-carriage portion"},"main":{"type":"number","description":"Ocean freight portion"},"onCarriage":{"type":"number","description":"On-carriage portion"}},"description":"Per-leg breakdown of the total amount"}},"required":["containerType","containerSize","amount","currency"]},"RateSurcharge":{"type":"object","properties":{"code":{"type":"string","description":"Surcharge code (e.g., BAF, CAF, THC)","example":"BAF"},"name":{"type":"string","description":"Surcharge display name","example":"Bunker Adjustment Factor"},"applicability":{"type":"string","enum":["inclusive","subject_to","not_subject_to","not_applicable"],"description":"Whether this surcharge is included in base rate or additional"},"basis":{"type":"string","description":"Charging basis (e.g., per_container, per_bl, percentage)","example":"per_container"},"amount":{"type":"number","description":"Default surcharge amount (when not container-specific)"},"currency":{"type":"string","example":"USD"},"containerRates":{"description":"Container-specific surcharge amounts","type":"array","items":{"$ref":"#/components/schemas/SurchargeContainerRate"}},"percentage":{"type":"number","description":"Percentage-based surcharge (if applicable)"},"applicablePorts":{"type":"array","items":{"type":"string"},"description":"Specific ports this surcharge applies to"},"effectiveDate":{"type":"string","format":"date"},"expiryDate":{"type":"string","format":"date"}},"required":["code","name","applicability"]},"SurchargeContainerRate":{"type":"object","properties":{"containerSize":{"type":"string","enum":["20ft","40ft","40ft_hc","45ft"]},"containerType":{"type":"string","enum":["dry","reefer","nor","general","all"]},"amount":{"type":"number"},"currency":{"type":"string","example":"USD"}},"required":["containerSize","amount","currency"]},"Organization":{"type":"object","description":"Organization/company information","properties":{"name":{"type":"string","description":"Organization name"},"code":{"type":"string","description":"Organization code or identifier","nullable":true}},"required":["name"]},"Address":{"type":"object","description":"Physical address","properties":{"street1":{"type":"string","description":"Street address line 1","nullable":true},"street2":{"type":"string","description":"Street address line 2","nullable":true},"city":{"type":"string","description":"City name","nullable":true},"state":{"type":"string","description":"State or province","nullable":true},"postalCode":{"type":"string","description":"Postal or ZIP code","nullable":true},"country":{"type":"string","description":"Country code (2-letter ISO)","nullable":true}}},"ImportProhibition":{"type":"object","description":"A ban on importing the goods at all — not a duty.\n\nSection 338(a) of the Tariff Act of 1930 lets the President escalate from an additional\nduty to excluding a country's articles from importation outright. There is no rate to pay\nand no Chapter 99 heading to file under: the entry cannot be made.\n\nTreat this as taking precedence over the duty figures returned alongside it. A prohibited\nline still computes a duty, and that number is meaningful — it is what an entry made\nbefore the effective date owes, and what would revive if the ban were struck down (the\nproclamations say so explicitly) — but it is not a price for importing the goods today.\n\nThe absence of this field means no ban was found for this code and origin. It is not an\naffirmative clearance to import.\n","properties":{"description":{"type":"string","description":"Human-readable statement of what may not be imported.","example":"Excluded from importation into the United States — Canadian alcoholic beverages (Proclamation of September 8, 2026, section 338(a))"},"effectiveFrom":{"type":"string","format":"date","description":"Date the ban takes effect. Note these run on goods IMPORTED on or after the date,\nnot entered for consumption, unlike most Chapter 99 effective dates.\n","example":"2026-09-29"},"authority":{"type":"string","description":"Statutory authority for the exclusion.","example":"section_338"},"sourceReference":{"type":"string","format":"uri","description":"URL of the proclamation or notice imposing the ban."},"condition":{"type":"string","description":"Present when the ban reaches only PART of the subheading and the classification alone\ncannot settle whether these goods fall inside it.\n\n`packaged` — only alcohol in bottles, cans, boxes, kegs or other similar\ndirect-to-consumption containers is excluded; bulk shipments under the same subheading\nremain importable and remain dutiable.\n\nWhen this field is present the finding is a WARNING, not a determination: the duties in\nthe same response still stand, and the importer must decide whether the goods meet the\nstated limitation.\n","example":"packaged"},"supersededDuties":{"type":"array","description":"Chapter 99 headings this ban replaced, and which have therefore been omitted from\n`additionalDuties`. The proclamations move a product OUT of the additional duty and\nINTO the ban rather than stacking the two. Empty for a conditional ban, which\nsupersedes nothing.\n","items":{"type":"string"},"example":["9903.03.12"]}},"required":["description","effectiveFrom"]},"UploadBatchCreatedEntity":{"type":"object","properties":{"entityType":{"type":"string","description":"Type of entity the batch produced","example":"shipment"},"entityId":{"type":"string","example":"1015989120405430278"},"documentIds":{"type":"array","items":{"type":"string"},"description":"Documents from the batch attached to this entity"},"isNew":{"type":"boolean","description":"False when the documents were attached to an entity that already existed\n(e.g. a shipment matched on its bill of lading). Absent on older batches.\n"}},"required":["entityType","entityId","documentIds"]},"UploadBatch":{"type":"object","properties":{"id":{"type":"string","example":"1017334964043997186"},"label":{"type":"string","nullable":true,"example":"Shipment 1"},"note":{"type":"string","nullable":true,"description":"Free-text context supplied with the upload"},"entryType":{"type":"string","nullable":true,"enum":["01","11","export","in_bond","ca_b3","ca_clvs","ca_type_f",null],"description":"Customs entry type hint. Customs-entry batches only."},"filingCountry":{"type":"string","nullable":true,"description":"ISO-2 filing country hint. Customs-entry batches only.","example":"US"},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"branchId":{"type":"string","nullable":true},"documentCount":{"type":"integer","description":"Documents created from the files, after zip expansion and splitting"},"sourceFileCount":{"type":"integer","description":"Files received, after zip expansion"},"duplicateFileCount":{"type":"integer","description":"Files skipped because identical content was already ingested for this batch"},"createdEntities":{"type":"array","description":"Entities the pipeline created or attached to. Empty until the batch completes.","items":{"$ref":"#/components/schemas/UploadBatchCreatedEntity"}},"unusedDocumentIds":{"type":"array","items":{"type":"string"},"description":"Documents the pipeline could not tie to any entity"},"error":{"type":"string","nullable":true,"description":"Failure reason when status is failed"},"processedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"externalShipmentRefId":{"type":"string","nullable":true,"description":"TMS job the documents were imported from. Null for file uploads."},"tmsSource":{"type":"string","nullable":true,"description":"TMS the documents were imported from. Null for file uploads."}},"required":["id","status","documentCount","createdEntities","unusedDocumentIds","createdAt"]},"CustomsEntryPort":{"type":"object","nullable":true,"properties":{"type":{"type":"string","example":"port"},"portCode":{"type":"string","example":"USLAX"},"portName":{"type":"string","example":"Los Angeles"},"country":{"type":"string","description":"ISO-2 country code, empty when the LOCODE is unknown","example":"US"}}},"CustomsEntry":{"type":"object","description":"A customs entry header. Decimal amounts stored as numerics (totalCustomsValue, totalDuties,\ntotalTaxes, totalFees) are returned as strings to preserve precision.\n","properties":{"id":{"type":"string","example":"1017334964043997190"},"shipmentId":{"type":"string","nullable":true},"branchId":{"type":"string","nullable":true},"teamId":{"type":"string","nullable":true},"entryNumber":{"type":"string","nullable":true},"entryType":{"type":"string","nullable":true,"enum":["01","11","export","in_bond","ca_b3","ca_clvs","ca_type_f",null]},"status":{"type":"string","enum":["pending","draft","review","filed","released","liquidated","cancelled"]},"syncStatus":{"type":"string","nullable":true,"description":"TMS sync status, separate from the customs status lifecycle"},"tmsSyncedAt":{"type":"string","format":"date-time","nullable":true},"complianceStatus":{"type":"string","nullable":true},"filingCountry":{"type":"string","nullable":true,"example":"US"},"customsAuthority":{"type":"string","nullable":true},"portOfEntry":{"$ref":"#/components/schemas/CustomsEntryPort"},"portOfLoading":{"$ref":"#/components/schemas/CustomsEntryPort"},"portOfOrigin":{"$ref":"#/components/schemas/CustomsEntryPort"},"portOfDischarge":{"$ref":"#/components/schemas/CustomsEntryPort"},"portOfDestination":{"$ref":"#/components/schemas/CustomsEntryPort"},"regime":{"type":"string","nullable":true},"importerName":{"type":"object","nullable":true,"description":"Party reference","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"importerAddress":{"type":"object","nullable":true},"importerTaxId":{"type":"string","nullable":true},"exporterName":{"type":"object","nullable":true,"description":"Party reference","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"exporterAddress":{"type":"object","nullable":true},"brokerName":{"type":"object","nullable":true,"description":"Party reference","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"brokerAddress":{"type":"object","nullable":true},"brokerReference":{"type":"string","nullable":true},"sendingAgentName":{"type":"object","nullable":true,"description":"Party reference","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"sendingAgentAddress":{"type":"object","nullable":true},"totalPacks":{"type":"number","nullable":true},"totalPacksPackageType":{"type":"string","nullable":true},"totalNoOfPieces":{"type":"number","nullable":true},"totalWeight":{"type":"number","nullable":true},"weightUnit":{"type":"string","nullable":true},"totalVolume":{"type":"number","nullable":true},"volumeUnit":{"type":"string","nullable":true},"entryDate":{"type":"string","format":"date","nullable":true},"arrivalDate":{"type":"string","format":"date-time","nullable":true},"releaseDate":{"type":"string","format":"date","nullable":true},"liquidationDate":{"type":"string","format":"date","nullable":true},"departureDate":{"type":"string","format":"date","nullable":true},"totalCustomsValue":{"type":"string","nullable":true,"example":"12500.00"},"totalDuties":{"type":"string","nullable":true},"totalTaxes":{"type":"string","nullable":true},"totalFees":{"type":"string","nullable":true},"currency":{"type":"string","nullable":true,"example":"USD"},"authorityReference":{"type":"string","nullable":true},"amendmentType":{"type":"string","nullable":true},"originalEntryNumber":{"type":"string","nullable":true},"filingMethod":{"type":"string","nullable":true},"sourceSystem":{"type":"string","nullable":true},"fieldSources":{"type":"object","nullable":true,"description":"Per-field provenance of extracted values"},"aiInputSnapshot":{"type":"object","nullable":true},"transportMode":{"type":"string","nullable":true},"vesselName":{"type":"string","nullable":true},"voyageFlightNo":{"type":"string","nullable":true},"lloydsImo":{"type":"string","nullable":true},"masterBill":{"type":"string","nullable":true},"houseBill":{"type":"string","nullable":true},"externalShipmentRefId":{"type":"string","nullable":true},"manifestNumber":{"type":"string","nullable":true},"poNumber":{"type":"string","nullable":true},"carrierCode":{"type":"string","nullable":true},"lvsId":{"type":"string","nullable":true},"cadTransactionNumber":{"type":"string","nullable":true},"portOfClearance":{"type":"string","nullable":true},"subLocationCode":{"type":"string","nullable":true},"subLocationDescription":{"type":"string","nullable":true},"examLocationCode":{"type":"string","nullable":true},"examLocationDescription":{"type":"string","nullable":true},"incoterm":{"type":"string","nullable":true},"carrier":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}},"previousExportMrn":{"type":"string","nullable":true},"deliveryNoteNumber":{"type":"string","nullable":true},"customsOfficeOfExit":{"type":"string","nullable":true},"vehicleRegistration":{"type":"string","nullable":true},"lineCount":{"type":"integer"},"documentCount":{"type":"integer"},"tmsReference":{"type":"string","nullable":true},"allTmsReferences":{"type":"string","nullable":true,"description":"Comma-separated list of every TMS reference the entry is synced under"},"tmsType":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string"}}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","status","createdAt","updatedAt"]},"CustomsEntryInvoice":{"type":"object","properties":{"id":{"type":"string"},"customsEntryId":{"type":"string"},"invoiceNumber":{"type":"string","nullable":true},"invoiceDate":{"type":"string","format":"date","nullable":true},"invoiceAmount":{"type":"number","nullable":true},"invoiceCurrency":{"type":"string","nullable":true},"incoTerm":{"type":"string","nullable":true},"incoTermPlace":{"type":"string","nullable":true},"paymentTerms":{"type":"string","nullable":true},"valuationBasis":{"type":"string","nullable":true},"supplierName":{"type":"object","nullable":true,"description":"Party reference","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"supplierAddress":{"type":"object","nullable":true},"supplierRegistrationNumbers":{"nullable":true},"buyerName":{"type":"object","nullable":true,"description":"Party reference","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"buyerAddress":{"type":"object","nullable":true},"buyerRegistrationNumbers":{"nullable":true},"commercialCharges":{"nullable":true},"noOfPacks":{"type":"number","nullable":true},"grossWeight":{"type":"number","nullable":true},"grossWeightUom":{"type":"string","nullable":true},"netWeight":{"type":"number","nullable":true},"netWeightUom":{"type":"string","nullable":true},"volume":{"type":"number","nullable":true},"volumeUom":{"type":"string","nullable":true},"exportLicenseNumber":{"type":"string","nullable":true},"preferentialOriginClaim":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CustomsEntryContainer":{"type":"object","properties":{"id":{"type":"string"},"customsEntryId":{"type":"string"},"containerNumber":{"type":"string","nullable":true},"containerType":{"type":"string","nullable":true},"sealNumber":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CustomsEntryPackingLine":{"type":"object","properties":{"id":{"type":"string"},"customsEntryId":{"type":"string"},"lineNumber":{"type":"integer","nullable":true},"packageNumbers":{"type":"string","nullable":true},"packageCount":{"type":"integer","nullable":true},"packageType":{"type":"string","nullable":true},"marksAndNumbers":{"type":"string","nullable":true},"sealNumber":{"type":"string","nullable":true},"grossWeight":{"type":"number","nullable":true},"grossWeightUom":{"type":"string","nullable":true},"netWeight":{"type":"number","nullable":true},"netWeightUom":{"type":"string","nullable":true},"tareWeight":{"type":"number","nullable":true},"tareWeightUom":{"type":"string","nullable":true},"length":{"type":"number","nullable":true},"width":{"type":"number","nullable":true},"height":{"type":"number","nullable":true},"dimensionUom":{"type":"string","nullable":true},"volume":{"type":"number","nullable":true},"volumeUom":{"type":"string","nullable":true},"countryOfOrigin":{"type":"string","nullable":true},"hsCode":{"type":"string","nullable":true},"fieldSources":{"type":"object","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CustomsEntryLine":{"type":"object","description":"A customs entry line. Decimal columns (values, quantities, weights, rates, amounts) are returned as strings.","properties":{"id":{"type":"string"},"customsEntryId":{"type":"string"},"customsEntryInvoiceId":{"type":"string","nullable":true},"lineNumber":{"type":"integer","nullable":true},"shipmentContainerId":{"type":"string","nullable":true},"shipmentPackageId":{"type":"string","nullable":true},"shipmentPackageItemId":{"type":"string","nullable":true},"sku":{"type":"string","nullable":true},"partNumber":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"hsCode":{"type":"string","nullable":true,"example":"8471300100"},"countryOfOrigin":{"type":"string","nullable":true,"example":"CN"},"customsValue":{"type":"string","nullable":true},"currency":{"type":"string","nullable":true},"customsQuantity":{"type":"string","nullable":true},"customsQuantityUom":{"type":"string","nullable":true},"statisticalQuantity":{"type":"string","nullable":true},"statisticalQuantityUom":{"type":"string","nullable":true},"grossWeight":{"type":"string","nullable":true},"grossWeightUom":{"type":"string","nullable":true},"netWeight":{"type":"string","nullable":true},"netWeightUom":{"type":"string","nullable":true},"volume":{"type":"string","nullable":true},"volumeUom":{"type":"string","nullable":true},"dutyRate":{"type":"string","nullable":true},"tariffTreatmentCode":{"type":"string","nullable":true},"dutyAmount":{"type":"string","nullable":true},"taxRate":{"type":"string","nullable":true},"taxAmount":{"type":"string","nullable":true},"lineStatus":{"type":"string","nullable":true,"enum":["draft","review","final","cancelled",null]},"pgaFlags":{"nullable":true},"fieldSources":{"type":"object","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"responses":{"UnauthorizedError":{"description":"Authentication required or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_token":{"summary":"Invalid or expired token","value":{"success":false,"error":{"code":"AUTHENTICATION_ERROR","message":"Invalid or expired access token"}}},"missing_auth":{"summary":"Missing authentication","value":{"success":false,"error":{"code":"AUTHENTICATION_ERROR","message":"Authentication required"}}}}}}},"ForbiddenError":{"description":"Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"insufficient_scope":{"summary":"Missing required scope","value":{"success":false,"error":{"code":"AUTHORIZATION_ERROR","message":"Insufficient scope: documents:read required"}}},"access_denied":{"summary":"Access denied to resource","value":{"success":false,"error":{"code":"AUTHORIZATION_ERROR","message":"Access denied to this resource"}}}}}}},"NotFoundError":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"NOT_FOUND","message":"Resource not found"}}}}},"BadRequestError":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validation_error":{"summary":"Validation error","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Invalid input parameters","details":{"field":"shipmentType","error":"Must be one of FCL, LCL, or Air"}}}},"missing_required":{"summary":"Missing required field","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Missing required field","details":{"field":"name","error":"Field is required\n"}}}}}}}},"RateLimitError":{"description":"Too many requests","headers":{"X-RateLimit-Limit-Minute":{"schema":{"type":"integer"},"description":"Requests per minute limit"},"X-RateLimit-Remaining-Minute":{"schema":{"type":"integer"},"description":"Remaining requests this minute"},"X-RateLimit-Reset-Minute":{"schema":{"type":"integer"},"description":"Unix timestamp when minute limit resets"},"X-RateLimit-Limit-Day":{"schema":{"type":"integer"},"description":"Requests per day limit"},"X-RateLimit-Remaining-Day":{"schema":{"type":"integer"},"description":"Remaining requests today"},"X-RateLimit-Reset-Day":{"schema":{"type":"integer"},"description":"Unix timestamp when daily limit resets"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"RATE_LIMIT_ERROR","message":"Too many requests. Please retry after some time.","details":{"retryAfter":60,"limit":60,"remaining":0}}}}}},"InternalServerError":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"INTERNAL_ERROR","message":"An internal error occurred. Please try again later."}}}}},"TmsOrganization":{"type":"object","properties":{"id":{"type":"string","example":"123456789"},"customerId":{"type":"string"},"source":{"type":"string","enum":["cw","gf","lw","ns"]},"code":{"type":"string","example":"ORG001"},"name":{"type":"string","example":"Acme Shipping Corp"},"types":{"type":"array","items":{"type":"string"},"nullable":true,"example":["consignee","shipper"]},"carrierCode":{"type":"string","nullable":true},"address1":{"type":"string","nullable":true},"address2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"phoneNumber":{"type":"string","nullable":true},"mobileNumber":{"type":"string","nullable":true},"faxNumber":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"metadata":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","customerId","source","code","name","isActive","createdAt","updatedAt"]},"CreateTmsOrganizationRequest":{"type":"object","properties":{"source":{"type":"string","enum":["cw","gf","lw","ns"]},"code":{"type":"string","example":"ORG001"},"name":{"type":"string","example":"Acme Shipping Corp"},"types":{"type":"array","items":{"type":"string"}},"carrierCode":{"type":"string"},"address1":{"type":"string"},"address2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"postalCode":{"type":"string"},"country":{"type":"string"},"phoneNumber":{"type":"string"},"mobileNumber":{"type":"string"},"faxNumber":{"type":"string"},"email":{"type":"string"},"website":{"type":"string"},"isActive":{"type":"boolean","default":true},"metadata":{"type":"object"}},"required":["source","code","name"]},"UpdateTmsOrganizationRequest":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"types":{"type":"array","items":{"type":"string"},"nullable":true},"carrierCode":{"type":"string","nullable":true},"address1":{"type":"string","nullable":true},"address2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"phoneNumber":{"type":"string","nullable":true},"mobileNumber":{"type":"string","nullable":true},"faxNumber":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"metadata":{"type":"object","nullable":true}}},"TmsOrganizationImportResponse":{"type":"object","properties":{"jobId":{"type":"string","description":"ID of the async import job"},"message":{"type":"string"}},"required":["jobId","message"]},"TmsOrganizationImportStatus":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"totalRows":{"type":"integer"},"processedRows":{"type":"integer"},"successfulRows":{"type":"integer"},"failedRows":{"type":"integer"},"percentComplete":{"type":"integer"}},"required":["jobId","status","totalRows","processedRows","successfulRows","failedRows","percentComplete"]}}},"security":[{"bearerAuth":[]}],"tags":[{"name":"Authentication","description":"OAuth 2.0 authentication endpoints"},{"name":"Testing","description":"Test endpoints for API validation"},{"name":"Shipments","description":"Shipment management operations"},{"name":"Documents","description":"Document management within shipments"},{"name":"Upload Batches","description":"Upload a group of files and let Wove create the shipments or customs entries they describe.\nCreation is asynchronous - poll the batch until it completes. Requires documents:read / documents:write\nplus the read / write scope of each object type (shipments:* or customs:*).\n"},{"name":"Customs Entries","description":"Read-only access to customs entries (requires customs:read)"},{"name":"Webhooks","description":"Webhook management for async notifications"},{"name":"Sources","description":"Rate sheet source management - upload, process, and query status"},{"name":"Query Bank","description":"Query Bank management - add/remove sources from your rate query pool"},{"name":"Rates","description":"Query freight rates from your Query Bank"},{"name":"Tariffs","description":"Duty and tariff rate lookup by HS code with customer-specific overrides"},{"name":"TMS Organizations","description":"TMS organization management - CRUD and bulk JSONL import"}],"paths":{"/api/v1/external/auth/token":{"post":{"tags":["Authentication"],"summary":"Get OAuth access token","description":"Obtain an access token using OAuth 2.0 client credentials flow.\nThis token is required for all other API endpoints.\n\n**Rate Limiting**: 100 requests per minute per IP address.\n","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"},"example":{"grant_type":"client_credentials","client_id":"wove_prod_abc123def456","client_secret":"sk_your_secret_key","scope":"shipments:read documents:read validation:create"}}}},"responses":{"200":{"description":"Access token generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"},"example":{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","token_type":"Bearer","expires_in":3600,"scope":"shipments:read documents:read validation:create"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid client credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/auth/revoke":{"post":{"tags":["Authentication"],"summary":"Revoke OAuth token","description":"Revoke an OAuth access token to immediately invalidate it.\nThis is useful when a token is compromised or no longer needed.\n","security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"The token to revoke (optional, defaults to current token)\n"},"token_type_hint":{"type":"string","enum":["access_token","refresh_token"],"description":"Hint about the token type"}}}}}},"responses":{"200":{"description":"Token revoked successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"},"example":{"success":true,"data":{"revoked":true},"message":"Token revoked successfully"}}}},"401":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/test/ping":{"get":{"tags":["Testing"],"summary":"Test API connectivity","description":"Simple ping endpoint to test API connectivity and authentication.\nReturns basic information about your authenticated session.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Ping successful","headers":{"X-RateLimit-Limit-Minute":{"schema":{"type":"integer"},"description":"Requests per minute limit"},"X-RateLimit-Remaining-Minute":{"schema":{"type":"integer"},"description":"Remaining requests this minute"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"},"example":{"success":true,"data":{"message":"pong","customerId":"1","clientId":"1014844138697089024","timestamp":"2025-07-12T00:30:05.083Z"}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/test/rate-limit-status":{"get":{"tags":["Testing"],"summary":"Get rate limit status","description":"Check your current rate limit usage and remaining quota.\nUseful for monitoring your API usage and planning requests.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Rate limit status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"limits":{"type":"object","properties":{"perMinute":{"type":"integer","example":60},"perDay":{"type":"integer","example":10000}}},"usage":{"type":"object","properties":{"minute":{"type":"integer","example":5},"day":{"type":"integer","example":150}}},"remaining":{"type":"object","properties":{"minute":{"type":"integer","example":55},"day":{"type":"integer","example":9850}}},"resetTimes":{"type":"object","properties":{"minute":{"type":"string","format":"date-time","example":"2025-07-12T00:32:00.000Z"},"day":{"type":"string","format":"date-time","example":"2025-07-13T00:00:00.000Z"}}}}}}}}}}}}},"/api/v1/external/test/protected":{"get":{"tags":["Testing"],"summary":"Test protected endpoint","description":"Test endpoint that requires authentication and specific scopes.\nUse this to verify that your OAuth token has the correct permissions.\n","security":[{"bearerAuth":["shipments:read"]}],"responses":{"200":{"description":"Access granted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"message":{"type":"string","example":"Access granted to protected endpoint"},"customerId":{"type":"string","example":"1"},"scopes":{"type":"array","items":{"type":"string"},"example":["shipments:read","documents:read"]}}}}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/test/api-usage-status":{"get":{"tags":["Testing"],"summary":"Get API usage statistics","description":"Get detailed API usage statistics for the current OAuth client.\nIncludes daily, monthly, and total usage metrics.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"API usage statistics retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"dailyUsage":{"type":"integer","example":150,"description":"Number of API calls made today"},"monthlyUsage":{"type":"integer","example":4523,"description":"Number of API calls made this month"},"totalUsage":{"type":"integer","example":15234,"description":"Total number of API calls made"},"lastRequest":{"type":"string","format":"date-time","example":"2025-07-12T00:30:05.083Z","description":"Timestamp of the last API request"},"averageResponseTime":{"type":"number","example":125.5,"description":"Average response time in milliseconds"}}}}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/shipments":{"get":{"tags":["Shipments"],"summary":"List shipments","description":"Retrieve a paginated list of shipments for your organization.\nResults are ordered by creation date (newest first).\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1},"description":"Page number for pagination"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Number of items per page"},{"name":"status","in":"query","schema":{"type":"string","enum":["draft","booked","pending","in_transit","delivered","cancelled"]},"description":"Filter by shipment status"},{"name":"shipmentType","in":"query","schema":{"type":"string","enum":["FCL","LCL","Air"]},"description":"Filter by shipment type"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Search shipments by name or ID"}],"responses":{"200":{"description":"Shipments retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentSummary"}},"pagination":{"type":"object","properties":{"page":{"type":"integer","example":1},"limit":{"type":"integer","example":20},"total":{"type":"integer","example":150},"totalPages":{"type":"integer","example":8},"hasNext":{"type":"boolean","example":true},"hasPrev":{"type":"boolean","example":false}}}}}}}}}}}},"post":{"tags":["Shipments"],"summary":"Create shipment","description":"Create a new shipment in draft status.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShipmentRequest"}}}},"responses":{"201":{"description":"Shipment created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentDetails"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/shipments/{shipmentId}":{"get":{"tags":["Shipments"],"summary":"Get shipment details","description":"Retrieve detailed information about a specific shipment.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"responses":{"200":{"description":"Shipment details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentDetails"}}}}}},"404":{"description":"Shipment not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"tags":["Shipments"],"summary":"Update shipment","description":"Update an existing shipment's details.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateShipmentRequest"}}}},"responses":{"200":{"description":"Shipment updated successfully\n","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentDetails"}}}}}},"404":{"description":"Shipment not found"}}},"delete":{"tags":["Shipments"],"summary":"Delete shipment","description":"Delete a shipment and all associated data.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"responses":{"204":{"description":"Shipment deleted successfully"},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/details":{"get":{"tags":["Shipments"],"summary":"Get detailed shipment information","description":"Retrieve comprehensive shipment details including items and containers.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"responses":{"200":{"description":"Detailed shipment information retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"shipment":{"$ref":"#/components/schemas/ShipmentDetails"},"items":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentItem"}},"containers":{"type":"array","items":{"$ref":"#/components/schemas/Container"}}}}}}}}},"404":{"description":"Shipment not found"}}},"put":{"tags":["Shipments"],"summary":"Update shipment information","description":"Update shipment-level details only. \nTo update containers, packages, or items, use the respective CRUD endpoints:\n- Containers: PUT /shipments/{shipmentId}/containers/{containerId}\n- Packages: PUT /shipments/{shipmentId}/packages/{packageId}\n- Items: PUT /shipments/{shipmentId}/items/{itemId}\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateShipmentDetailsRequest"}}}},"responses":{"200":{"description":"Shipment details updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentDetails"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request parameters"},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/events":{"get":{"tags":["Shipments"],"summary":"Get shipment events","description":"Retrieve chronological events and milestones for a shipment.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"responses":{"200":{"description":"Shipment events retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentEvent"}}}}}}}}},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/documents":{"get":{"tags":["Documents"],"summary":"List shipment documents","description":"Retrieve all documents associated with a specific shipment.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"includeDeleted","in":"query","schema":{"type":"boolean"},"description":"Include deleted documents in the response"},{"name":"documentTypes","in":"query","schema":{"type":"string"},"description":"Filter by document types (comma-separated)"},{"name":"status","in":"query","schema":{"type":"string","enum":["uploaded","processing","completed","failed"]},"description":"Filter by document status"}],"responses":{"200":{"description":"Documents retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}}}}}}}},"post":{"tags":["Documents"],"summary":"Upload document","description":"Upload a single document to a shipment.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"File to upload"},"documentType":{"type":"string","description":"Document type","example":"CommercialInvoice"}},"required":["file"]}}}},"responses":{"201":{"description":"Document uploaded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Document"},"message":{"type":"string","example":"Document uploaded successfully and extraction queued"}}}}}}}}},"/api/v1/external/shipments/{shipmentId}/documents/{documentId}":{"get":{"tags":["Documents"],"summary":"Get document details","description":"Retrieve detailed information about a specific document.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique document identifier"}],"responses":{"200":{"description":"Document details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"allOf":[{"$ref":"#/components/schemas/Document"},{"type":"object","properties":{"validationItems":{"type":"array","items":{"type":"object"},"description":"Associated validation items"}}}]}}}}}},"404":{"description":"Document not found"}}},"put":{"tags":["Documents"],"summary":"Update document","description":"Update document metadata or type.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique document identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"Document type"},"name":{"type":"string","description":"Document name"},"isSelected":{"type":"boolean","description":"Whether document is selected"}}}}}},"responses":{"200":{"description":"Document updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Document"}}}}}}}},"delete":{"tags":["Documents"],"summary":"Delete document","description":"Delete a document from the system.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique document identifier"}],"responses":{"204":{"description":"Document deleted successfully"},"404":{"description":"Document not found"}}}},"/api/v1/external/shipments/{shipmentId}/documents/{documentId}/download":{"get":{"tags":["Documents"],"summary":"Download document","description":"Download the original document file.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique document identifier"}],"responses":{"200":{"description":"Document file","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Document not found"}}}},"/api/v1/external/shipments/{shipmentId}/documents/{documentId}/extraction":{"get":{"tags":["Documents"],"summary":"Get extraction status","description":"Get the extraction status and results for a document.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique document identifier"}],"responses":{"200":{"description":"Extraction status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"status":{"type":"string","enum":["pending","processing","completed","failed"]},"extractedData":{"type":"object"},"confidence":{"type":"number"},"extractedAt":{"type":"string","format":"date-time"},"extractionMethod":{"type":"string"}}}}}}}}}}},"/api/v1/external/shipments/{shipmentId}/documents/{documentId}/extract":{"post":{"tags":["Documents"],"summary":"Start extraction","description":"Start or restart extraction for a document.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique document identifier"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reprocess":{"type":"boolean","description":"Force reprocessing even if already extracted"},"fields":{"type":"array","items":{"type":"string"},"description":"Specific fields to extract"}}}}}},"responses":{"200":{"description":"Extraction started successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"jobId":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/api/v1/external/shipments/{shipmentId}/documents/{documentId}/extracted-data":{"put":{"tags":["Documents"],"summary":"Update extracted data","description":"Manually update the extracted data for a document.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique document identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"The extracted data"},"changes":{"type":"object","description":"Description of changes made"}},"required":["data","changes"]}}}},"responses":{"200":{"description":"Extracted data updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"},"message":{"type":"string"}}}}}}}}},"/api/v1/external/shipments/{shipmentId}/documents/{documentId}/history":{"get":{"tags":["Documents"],"summary":"Get document history","description":"Get the history of changes for a document.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique document identifier"}],"responses":{"200":{"description":"Document history retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/DocumentHistoryEntry"}}}}}}}}}},"/api/v1/external/shipments/{shipmentId}/documents/validate":{"post":{"tags":["Documents"],"summary":"Validate documents","description":"Validate specific documents within a shipment.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"documentIds":{"type":"array","items":{"type":"string"},"minItems":1}},"required":["documentIds"]}}}},"responses":{"200":{"description":"Validation completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"status":{"type":"string","enum":["valid","errors"]},"issues":{"type":"array","items":{"type":"object"}},"validatedAt":{"type":"string","format":"date-time"},"documentIds":{"type":"array","items":{"type":"string"}}}}}}}}}}}},"/api/v1/external/shipments/{shipmentId}/documents/cross-validate/{jobId}":{"get":{"tags":["Documents"],"summary":"Get cross-validation job status","description":"Check the status and results of a cross-validation job.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique job identifier"}],"responses":{"200":{"description":"Cross-validation status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"progress":{"type":"number"},"result":{"type":"object","nullable":true,"properties":{"validatedFields":{"type":"array","items":{"type":"string"}},"issues":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"},"severity":{"type":"string","enum":["critical","warning"]},"suggestion":{"type":"string","nullable":true},"files":{"type":"array","items":{"type":"string"}},"documents":{"type":"array","items":{"type":"string"}}}}}}},"error":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time","nullable":true},"completedAt":{"type":"string","format":"date-time","nullable":true}}}}}}}}}},"404":{"description":"Job not found"}}}},"/api/v1/external/shipments/{shipmentId}/documents/merge/{jobId}":{"get":{"tags":["Documents"],"summary":"Get merge job status","description":"Check the status and results of a document merge operation.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique job identifier"}],"responses":{"200":{"description":"Merge status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"progress":{"type":"number"},"result":{"nullable":true},"error":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time","nullable":true},"completedAt":{"type":"string","format":"date-time","nullable":true}}}}}}}}}},"404":{"description":"Job not found"}}}},"/api/v1/external/shipments/{shipmentId}/validation-items":{"get":{"tags":["Shipments"],"summary":"Get validation items","description":"Retrieve all validation items for a shipment with optional filtering.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by validation item status"},{"name":"actionStatus","in":"query","schema":{"type":"string","enum":["PENDING","ACCEPTED","IGNORED","OVERRIDDEN"]},"description":"Filter by validation item action status"}],"responses":{"200":{"description":"Validation items retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ValidationItem"}}}}}}},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/validation-items/{itemId}":{"put":{"tags":["Shipments"],"summary":"Update validation item","description":"Update the action status and details of a validation item.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"itemId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique validation item identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateValidationItemRequest"}}}},"responses":{"200":{"description":"Validation item updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","example":"Validation item updated successfully"}}}}}},"400":{"description":"Invalid request"},"404":{"description":"Validation item or shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/validation-items/bulk-update":{"post":{"tags":["Shipments"],"summary":"Bulk update validation items","description":"Update multiple validation items at once with the same action.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"itemIds":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":100,"description":"Array of validation item IDs to update"},"actionStatus":{"type":"string","enum":["ACCEPTED","IGNORED","OVERRIDDEN"],"description":"Action to apply to all items"},"actionReason":{"type":"string","description":"Optional reason explaining the action"}},"required":["itemIds","actionStatus"]}}}},"responses":{"200":{"description":"Validation items updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","nullable":true},"message":{"type":"string","example":"5 validation items updated successfully"}}}}}},"400":{"description":"Invalid request"},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/jobs":{"get":{"tags":["Shipments"],"summary":"Get shipment jobs","description":"Retrieve all background jobs (extraction, validation, merge) for a shipment.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"responses":{"200":{"description":"Jobs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"jobs":{"type":"object","properties":{"crossValidation":{"type":"array","items":{"$ref":"#/components/schemas/CrossValidationJob"}},"merge":{"type":"array","items":{"$ref":"#/components/schemas/MergeJob"}}}}}}}}}}},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/documents/cross-validate":{"post":{"tags":["Documents"],"summary":"Cross-validate documents","description":"Create a cross-validation job to check for inconsistencies between documents in a shipment.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateDocumentsRequest"}}}},"responses":{"200":{"description":"Cross-validation job created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"jobId":{"type":"string"},"message":{"type":"string"}}}}}}}},"400":{"description":"Invalid request"},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/documents/merge":{"post":{"tags":["Documents"],"summary":"Merge shipment documents","description":"Create a job to merge data from multiple documents within a shipment.\nIntelligently combines data from related documents (e.g., commercial invoice and packing list).\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MergeDocumentsRequest"}}}},"responses":{"200":{"description":"Merge job created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/MergeJobResponse"}}}}}},"400":{"description":"Invalid request or documents not found"},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/documents/analyze-types":{"post":{"tags":["Documents"],"summary":"Analyze document types","description":"Analyze a document to detect multiple document types within it.\nFor PDFs, this will identify different document types and their page boundaries.\nFor other file types, it will identify the document type based on content.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"The document file to analyze"}},"required":["file"]}}}},"responses":{"200":{"description":"Document analysis completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"types":{"type":"array","description":"Array of detected document types and their boundaries","items":{"type":"object","properties":{"documentType":{"type":"string","description":"Type of document detected","enum":["CommercialInvoice","PackingList","BillOfLading","AirWaybill","CertificateOfOrigin","DangerousGoodsDeclaration","Other"]},"startPage":{"type":"integer","nullable":true,"description":"Starting page number (1-indexed) for PDFs"},"endPage":{"type":"integer","nullable":true,"description":"Ending page number (1-indexed) for PDFs"},"confidence":{"type":"string","enum":["high","medium","low"],"description":"Confidence level of the detection"}}}},"totalPages":{"type":"integer","description":"Total number of pages in the document (for PDFs)"},"requiresSplit":{"type":"boolean","description":"Whether the document contains multiple types requiring split"}}}}}}}},"400":{"description":"Invalid file or request"},"404":{"description":"Shipment not found"},"413":{"description":"File too large"}}}},"/api/v1/external/shipments/{shipmentId}/documents/upload-multi":{"post":{"tags":["Documents"],"summary":"Upload multi-document file","description":"Upload a file containing multiple documents.\nFor PDFs with multiple document types, this will create separate document records for each type.\nThe original file is stored once, with virtual splits created for each document type.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"The document file to upload"},"types":{"type":"string","description":"JSON string containing array of document types with page ranges","example":"[{\"documentType\":\"BillOfLading\",\"startPage\":1,\"endPage\":2},{\"documentType\":\"CommercialInvoice\",\"startPage\":3,\"endPage\":4}]"}},"required":["file","types"]}}}},"responses":{"200":{"description":"Documents uploaded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"documents":{"type":"array","description":"Array of created document records","items":{"type":"object","properties":{"id":{"type":"string","description":"Document ID"},"type":{"type":"string","description":"Document type"},"name":{"type":"string","description":"Generated document name"},"startPage":{"type":"integer","nullable":true,"description":"Start page for split documents"},"endPage":{"type":"integer","nullable":true,"description":"End page for split documents"},"isSplit":{"type":"boolean","description":"Whether this is a split document"}}}}}}}}}}},"400":{"description":"Invalid file or types specification"},"404":{"description":"Shipment not found"},"413":{"description":"File too large"}}}},"/api/v1/external/shipments/{shipmentId}/containers":{"get":{"tags":["Shipments"],"summary":"List containers","description":"Retrieve all containers for a specific shipment.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"responses":{"200":{"description":"Containers retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"containers":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentContainer"}}}}}}}}},"404":{"description":"Shipment not found"}}},"post":{"tags":["Shipments"],"summary":"Create container","description":"Add a new container to a shipment.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContainerRequest"}}}},"responses":{"201":{"description":"Container created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentContainer"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/containers/{containerId}":{"put":{"tags":["Shipments"],"summary":"Update container","description":"Update an existing container's details.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"containerId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique container identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContainerRequest"}}}},"responses":{"200":{"description":"Container updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentContainer"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"Container or shipment not found"}}},"delete":{"tags":["Shipments"],"summary":"Delete container","description":"Remove a container from a shipment. Associated packages will become loose packages.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"containerId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique container identifier"}],"responses":{"200":{"description":"Container deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"success":{"type":"boolean"}}},"message":{"type":"string"}}}}}},"404":{"description":"Container or shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/packages":{"get":{"tags":["Shipments"],"summary":"List packages","description":"Retrieve all packages for a specific shipment, optionally filtered by container.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"containerId","in":"query","required":false,"schema":{"type":"string","nullable":true},"description":"Filter packages by container ID (use 'null' for loose packages)"}],"responses":{"200":{"description":"Packages retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"packages":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentPackage"}}}}}}}}},"404":{"description":"Shipment not found"}}},"post":{"tags":["Shipments"],"summary":"Create package","description":"Add a new package to a shipment (either in a container or as a loose package).","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePackageRequest"}}}},"responses":{"201":{"description":"Package created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentPackage"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"Shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/packages/{packageId}":{"put":{"tags":["Shipments"],"summary":"Update package","description":"Update an existing package's details.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"packageId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique package identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePackageRequest"}}}},"responses":{"200":{"description":"Package updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentPackage"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"Package or shipment not found"}}},"delete":{"tags":["Shipments"],"summary":"Delete package","description":"Remove a package from a shipment. Associated items will be deleted.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"packageId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique package identifier"}],"responses":{"200":{"description":"Package deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"success":{"type":"boolean"}}},"message":{"type":"string"}}}}}},"404":{"description":"Package or shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/packages/{packageId}/move":{"post":{"tags":["Shipments"],"summary":"Move package","description":"Move a package to a different container or make it a loose package.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"packageId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique package identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"containerId":{"type":"string","nullable":true,"description":"Target container ID (null to make it a loose package)"}},"required":["containerId"]}}}},"responses":{"200":{"description":"Package moved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"Package, container, or shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/items":{"get":{"tags":["Shipments"],"summary":"List items","description":"Retrieve all items for a specific shipment, optionally filtered by package.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"packageId","in":"query","required":false,"schema":{"type":"string"},"description":"Filter items by package ID"}],"responses":{"200":{"description":"Items retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentItem"}}}}}}}}},"404":{"description":"Shipment not found"}}},"post":{"tags":["Shipments"],"summary":"Create item","description":"Add a new item to a package.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateItemRequest"}}}},"responses":{"201":{"description":"Item created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentItem"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"Shipment or package not found"}}}},"/api/v1/external/shipments/{shipmentId}/items/{itemId}":{"put":{"tags":["Shipments"],"summary":"Update item","description":"Update an existing item's details.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"itemId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique item identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateItemRequest"}}}},"responses":{"200":{"description":"Item updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShipmentItem"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"Item or shipment not found"}}},"delete":{"tags":["Shipments"],"summary":"Delete item","description":"Remove an item from a package.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"itemId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique item identifier"}],"responses":{"200":{"description":"Item deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"success":{"type":"boolean"}}},"message":{"type":"string"}}}}}},"404":{"description":"Item or shipment not found"}}}},"/api/v1/external/shipments/{shipmentId}/items/{itemId}/move":{"post":{"tags":["Shipments"],"summary":"Move item","description":"Move an item to a different package.","security":[{"bearerAuth":[]}],"parameters":[{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique shipment identifier"},{"name":"itemId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique item identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"packageId":{"type":"string","nullable":true,"description":"Target package ID"},"containerId":{"type":"string","nullable":true,"description":"Target container ID (optional)"}},"required":["packageId"]}}}},"responses":{"200":{"description":"Item moved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"Item, package, or shipment not found"}}}},"/api/v1/external/entities/{entityType}/{entityId}/documents":{"get":{"tags":["Documents"],"summary":"List entity documents","description":"Retrieve all documents associated with a specific entity.\nSupports any entity type (shipment, rfq_shipment, etc.).\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"},{"name":"includeDeleted","in":"query","schema":{"type":"boolean"},"description":"Include deleted documents"},{"name":"documentTypes","in":"query","schema":{"type":"string"},"description":"Comma-separated list of document types to filter"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","processing","completed","failed"]},"description":"Filter by document status"}],"responses":{"200":{"description":"Documents retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}}}}}},"404":{"description":"Entity not found"}}},"post":{"tags":["Documents"],"summary":"Upload document to entity","description":"Upload a single document and attach it to an entity.\nDocument type can be auto-detected or explicitly specified.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Document file to upload"},"documentType":{"type":"string","description":"Document type (optional, will be auto-detected if not provided)"}}}}}},"responses":{"201":{"description":"Document uploaded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Document"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid file or parameters"},"404":{"description":"Entity not found"}}}},"/api/v1/external/entities/{entityType}/{entityId}/documents/multi":{"post":{"tags":["Documents"],"summary":"Upload multi-document PDF","description":"Upload a single PDF file containing multiple documents.\nThe system will automatically split and classify each document.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Multi-document PDF file"},"types":{"type":"array","items":{"type":"string"},"description":"Expected document types (helps with classification)"}}}}}},"responses":{"201":{"description":"Documents uploaded and split successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"jobId":{"type":"string","description":"Job ID for tracking processing status"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}}},"message":{"type":"string"}}}}}},"400":{"description":"Invalid file or parameters"},"404":{"description":"Entity not found"}}}},"/api/v1/external/entities/{entityType}/{entityId}/documents/{documentId}":{"get":{"tags":["Documents"],"summary":"Get document details","description":"Retrieve detailed information about a specific document.","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"}],"responses":{"200":{"description":"Document retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Document"}}}}}},"404":{"description":"Document or entity not found"}}},"put":{"tags":["Documents"],"summary":"Update document metadata","description":"Update document type or other metadata.","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"documentType":{"type":"string","description":"New document type"}}}}}},"responses":{"200":{"description":"Document updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Document"},"message":{"type":"string"}}}}}},"404":{"description":"Document or entity not found"}}},"delete":{"tags":["Documents"],"summary":"Delete document","description":"Delete a document from an entity.","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"}],"responses":{"204":{"description":"Document deleted successfully"},"404":{"description":"Document or entity not found"}}}},"/api/v1/external/entities/{entityType}/{entityId}/documents/{documentId}/download":{"get":{"tags":["Documents"],"summary":"Download document","description":"Download the original document file.","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"}],"responses":{"200":{"description":"Document file","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Document or entity not found"}}}},"/api/v1/external/entities/{entityType}/{entityId}/documents/{documentId}/preview":{"get":{"tags":["Documents"],"summary":"Get document preview URL","description":"Get a presigned URL for previewing the document.","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"},{"name":"purpose","in":"query","schema":{"type":"string"},"description":"Purpose of the preview (for tracking)"}],"responses":{"200":{"description":"Preview URL generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"url":{"type":"string","description":"Presigned URL for document preview"},"expiresAt":{"type":"string","format":"date-time","description":"URL expiration time"}}}}}}}},"404":{"description":"Document or entity not found"}}}},"/api/v1/external/entities/{entityType}/{entityId}/documents/{documentId}/history":{"get":{"tags":["Documents"],"summary":"Get document history","description":"Retrieve the processing history of a document.","security":[{"bearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["shipment","rfq_shipment"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string"},"description":"Entity ID"},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"}],"responses":{"200":{"description":"Document history retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/DocumentHistoryEntry"}}}}}}},"404":{"description":"Document or entity not found"}}}},"/api/v1/external/upload-batches":{"post":{"tags":["Upload Batches"],"summary":"Create upload batch","description":"Upload a group of files (e.g. one shipment's paperwork) and let Wove's object-creation pipeline\ncreate the shipments, shipment events or customs entries they describe.\n\nProcessing is asynchronous: the batch is returned with status `pending`, moves to `processing`,\nand ends as `completed` or `failed`. Poll `GET /api/v1/external/upload-batches/{batchId}` and read\n`createdEntities` once it has completed.\n\n**Required scopes:** `documents:write`, plus the write scope of every type in\n`allowedObjectTypes` (`shipment` / `shipment_event` → `shipments:write`,\n`customs_entry` → `customs:write`). When `allowedObjectTypes` is omitted the batch is unrestricted\nand requires `shipments:write`.\n","security":[{"bearerAuth":["documents:write"]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"type":"string","format":"binary"},"minItems":1,"maxItems":50,"description":"1-50 files, up to 50 MB each. Zip archives are expanded."},"label":{"type":"string","description":"Display label for the batch","example":"Shipment 1"},"note":{"type":"string","description":"Free-text context for the pipeline (stands in for an email body)"},"branchId":{"type":"string","description":"Branch to assign. Must belong to your organization."},"allowedObjectTypes":{"type":"array","items":{"type":"string","enum":["shipment","shipment_event","customs_entry"]},"description":"Restricts what the batch may create. Send the field repeated or as one comma-separated\nvalue. Any other value is rejected with 400. Omit for an unrestricted batch.\n"},"entryType":{"type":"string","enum":["01","11","export","in_bond","ca_b3","ca_clvs","ca_type_f"],"description":"Customs entry type hint for customs-entry batches. Unrecognized values are ignored."},"filingCountry":{"type":"string","description":"ISO-2 filing country hint for customs-entry batches","example":"US"}},"required":["files"]},"encoding":{"allowedObjectTypes":{"style":"form","explode":true}}}}},"responses":{"201":{"description":"Batch created and queued for processing","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/UploadBatch"}}}}}},"400":{"description":"No files, too many or oversized files, an unsupported allowedObjectTypes value, or an invalid/unknown branchId","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Missing documents:write or the write scope for a requested object type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"tags":["Upload Batches"],"summary":"List upload batches","description":"List your organization's most recent upload batches, newest first. Only batches whose object types\nyou can read are returned.\n\n**Required scopes:** `documents:read`, plus the read scope of a batch's object types\n(`shipments:read` or `customs:read`; `shipments:read` for unrestricted batches).\n","security":[{"bearerAuth":["documents:read"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Maximum number of batches to return"}],"responses":{"200":{"description":"Upload batches retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"batches":{"type":"array","items":{"$ref":"#/components/schemas/UploadBatch"}}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"}}}},"/api/v1/external/upload-batches/{batchId}":{"get":{"tags":["Upload Batches"],"summary":"Get upload batch","description":"Poll a batch for its status and, once `completed`, the entities it created.\n\n**Required scopes:** `documents:read`, plus the read scope of any one of the batch's object types\n(`shipments:read` or `customs:read`; `shipments:read` for unrestricted batches).\n","security":[{"bearerAuth":["documents:read"]}],"parameters":[{"name":"batchId","in":"path","required":true,"schema":{"type":"string"},"description":"Upload batch identifier"}],"responses":{"200":{"description":"Upload batch retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/UploadBatch"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Missing documents:read or a read scope for this batch's object types","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/api/v1/external/customs-entries":{"get":{"tags":["Customs Entries"],"summary":"List customs entries","description":"Retrieve a paginated list of your organization's customs entries, newest first. Requires `customs:read`.\n","security":[{"bearerAuth":["customs:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1},"description":"Page number for pagination"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"description":"Number of items per page"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","draft","review","filed","released","liquidated","cancelled"]},"description":"Filter by customs entry status"},{"name":"entryType","in":"query","schema":{"type":"string","enum":["01","11","export","in_bond","ca_b3","ca_clvs","ca_type_f"]},"description":"Filter by entry type. Any other value returns 400."},{"name":"filingCountry","in":"query","schema":{"type":"string","example":"US"},"description":"Filter by ISO-2 filing country"},{"name":"shipmentId","in":"query","schema":{"type":"string"},"description":"Only entries linked to this shipment"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Search entry number, TMS reference, importer name and broker name.\nWhen set, createdAfter/createdBefore are ignored.\n"},{"name":"createdAfter","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only entries created at or after this ISO 8601 date"},{"name":"createdBefore","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only entries created at or before this ISO 8601 date"}],"responses":{"200":{"description":"Customs entries retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PaginatedResponse"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CustomsEntry"}}}}]}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"}}}},"/api/v1/external/customs-entries/{entryId}":{"get":{"tags":["Customs Entries"],"summary":"Get customs entry","description":"Retrieve a customs entry header. Requires `customs:read`.","security":[{"bearerAuth":["customs:read"]}],"parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"string"},"description":"Customs entry identifier"}],"responses":{"200":{"description":"Customs entry retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CustomsEntry"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/api/v1/external/customs-entries/{entryId}/details":{"get":{"tags":["Customs Entries"],"summary":"Get customs entry details","description":"Retrieve a customs entry with its invoices, containers and packing lines, plus its lines.\nRequires `customs:read`.\n","security":[{"bearerAuth":["customs:read"]}],"parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"string"},"description":"Customs entry identifier"}],"responses":{"200":{"description":"Customs entry details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"customsEntry":{"allOf":[{"$ref":"#/components/schemas/CustomsEntry"},{"type":"object","properties":{"invoices":{"type":"array","items":{"$ref":"#/components/schemas/CustomsEntryInvoice"}},"containers":{"type":"array","items":{"$ref":"#/components/schemas/CustomsEntryContainer"}},"packingLines":{"type":"array","items":{"$ref":"#/components/schemas/CustomsEntryPackingLine"}}}}]},"lines":{"type":"array","items":{"$ref":"#/components/schemas/CustomsEntryLine"}}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/api/v1/external/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks","description":"Retrieve all configured webhooks for your organization.\n\n\nThe following events can trigger webhooks:\n- `extraction.completed` - Document extraction successful\n- `extraction.failed` - Document extraction failed\n- `validation.completed` - Cross-validation completed\n- `validation.failed` - Cross-validation failed\n- `merge.completed` - Document merge completed\n- `merge.failed` - Document merge failed\n- `document.uploaded` - New document uploaded\n- `document.deleted` - Document deleted\n- `shipment.created` - Shipment created\n- `shipment.updated` - Shipment updated\n- `source.processing.completed` - Rate sheet source processing completed\n- `source.processing.failed` - Rate sheet source processing failed\n\n\nAll webhook payloads follow this structure:\n```json\n{\n  \"event\": \"extraction.completed\",\n  \"timestamp\": \"2024-01-15T10:30:00.000Z\",\n  \"data\": { /* event-specific data */ }\n}\n```\n\nSee the schemas section for detailed payload structures for each event type.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Webhooks retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}}}},"post":{"tags":["Webhooks"],"summary":"Create webhook","description":"Create a new webhook endpoint for receiving notifications.\n\n\n```json\n{\n  \"event\": \"extraction.completed\",\n  \"timestamp\": \"2024-01-15T10:30:00.000Z\",\n  \"data\": {\n    \"document\": { /* WebhookDocument object */ },\n    \"entityType\": \"shipments\",\n    \"entityId\": \"1014560123456789012\"\n  }\n}\n```\n\n```json\n{\n  \"event\": \"validation.completed\",\n  \"timestamp\": \"2024-01-15T10:30:00.000Z\",\n  \"data\": {\n    \"jobId\": \"1014560123456789012\",\n    \"entityId\": \"1014560123456789012\",\n    \"entityType\": \"shipments\",\n    \"documents\": [ /* array of WebhookDocument objects */ ],\n    \"validationResult\": { /* validation results */ },\n    \"itemsValidated\": 15,\n    \"issuesFound\": 2,\n    \"completedAt\": \"2024-01-15T10:30:00.000Z\",\n    \"type\": \"cross-validation\"\n  }\n}\n```\n","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"},"examples":{"allEvents":{"summary":"Subscribe to all document events","value":{"url":"https://your-app.com/webhooks","events":["extraction.completed","extraction.failed","validation.completed","validation.failed","merge.completed","merge.failed"],"description":"Production webhook for document processing"}},"extractionOnly":{"summary":"Subscribe to extraction events only","value":{"url":"https://your-app.com/webhooks/extraction","events":["extraction.completed","extraction.failed"],"description":"Extraction notifications"}}}}}},"responses":{"201":{"description":"Webhook created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"allOf":[{"$ref":"#/components/schemas/Webhook"},{"type":"object","properties":{"secret":{"type":"string","description":"Webhook secret for signature verification","example":"whsec_1234567890abcdef"}}}]}}}}}},"400":{"description":"Invalid request parameters"}}}},"/api/v1/external/webhooks/{webhookId}":{"get":{"tags":["Webhooks"],"summary":"Get webhook details","description":"Retrieve details of a specific webhook.","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique webhook identifier"}],"responses":{"200":{"description":"Webhook details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Webhook"}}}}}},"404":{"description":"Webhook not found"}}},"put":{"tags":["Webhooks"],"summary":"Update webhook","description":"Update webhook configuration.","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique webhook identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"description":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}}}}}}},"responses":{"200":{"description":"Webhook updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Webhook"}}}}}},"404":{"description":"Webhook not found"}}},"delete":{"tags":["Webhooks"],"summary":"Delete webhook","description":"Delete a webhook endpoint.","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique webhook identifier"}],"responses":{"200":{"description":"Webhook deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"404":{"description":"Webhook not found"}}}},"/api/v1/external/webhooks/{webhookId}/test":{"post":{"tags":["Webhooks"],"summary":"Test webhook","description":"Send a test event to the webhook endpoint.","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique webhook identifier"}],"responses":{"200":{"description":"Test completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"status":{"type":"string","enum":["success","failed"]},"statusCode":{"type":"integer"},"duration":{"type":"integer","description":"Response time in milliseconds"},"response":{"type":"string","description":"Response body from webhook endpoint"}}}}}}}},"404":{"description":"Webhook not found"}}}},"/api/v1/external/webhooks/test":{"post":{"tags":["Webhooks"],"summary":"Test webhook URL","description":"Test a webhook URL before creating it.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL to test"},"event":{"type":"string","description":"Event type to simulate","default":"webhook.test"}},"required":["url"]}}}},"responses":{"200":{"description":"Test completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"message":{"type":"string"},"payload":{"type":"object","description":"The test payload that was sent"}}}}}}}},"400":{"description":"Invalid URL or test failed"}}}},"/api/v1/external/webhooks/{webhookId}/deliveries":{"get":{"tags":["Webhooks"],"summary":"Get webhook deliveries","description":"Retrieve delivery history for a webhook.","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"Unique webhook identifier"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Number of deliveries to return"}],"responses":{"200":{"description":"Delivery history retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"status":{"type":"string","enum":["success","failed","pending"]},"attempt":{"type":"integer"},"responseStatus":{"type":"integer"},"error":{"type":"string","description":"Error message if failed"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"}}}}}}}}},"404":{"description":"Webhook not found"}}}},"/api/v1/external/documents/guess-type":{"post":{"tags":["Documents"],"summary":"Guess document type","description":"Intelligently guess the type of a document based on its filename and optionally its content.\nUses AI-powered detection to analyze filename patterns and file content for accurate type identification.\n\n**File size limit**: 50MB when uploading file content\n\n**Supported file types for content analysis**:\n- Images (JPEG, PNG, etc.)\n- PDFs\n- Spreadsheets (Excel, CSV)\n- Word documents (DOCX)\n","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"fileName":{"type":"string","description":"The name of the file to analyze","example":"Packing_List_ABC.xlsx"},"file":{"type":"string","format":"binary","description":"Optional file content for more accurate type detection"}},"required":["fileName"]}}}},"responses":{"200":{"description":"Document type guessed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentType":{"type":"string","description":"The detected document type","enum":["CommercialInvoice","PackingList","BillOfLading","AirWaybill","CertificateOfOrigin","DangerousGoodsDeclaration","InsuranceCertificate","SafetyDataSheet","BookingConfirmation","APInvoice","ARInvoice","PaymentConfirmation","ISFFiling","Other"],"example":"CommercialInvoice"},"confidence":{"type":"string","description":"Confidence level of the detection","enum":["high","low"],"example":"high"},"fileName":{"type":"string","description":"The analyzed filename","example":"Commercial_Invoice_123.pdf"},"fileAnalyzed":{"type":"boolean","description":"Whether file content was analyzed (in addition to filename)","example":false}}}}},"example":{"success":true,"data":{"documentType":"CommercialInvoice","confidence":"high","fileName":"Commercial_Invoice_123.pdf","fileAnalyzed":false}}}}},"400":{"description":"Bad request - missing required parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"BAD_REQUEST","message":"fileName is required"}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"FORBIDDEN","message":"Insufficient scope: documents:read required"}}}}}}}},"/api/v1/external/sources/upload":{"post":{"tags":["Sources"],"summary":"Get presigned URL for source upload","description":"Creates a new source record and returns a presigned URL for uploading a rate sheet file.\n\n**Workflow**:\n1. Call this endpoint with file metadata\n2. Upload the file directly to the returned presigned URL using PUT\n3. Call POST /sources/{sourceId}/process to start processing\n\n**Supported file types**: Excel (.xlsx, .xls), CSV, PDF\n\n**File size limit**: 50MB\n","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceUploadRequest"},"example":{"filename":"carrier_rates_2024.xlsx","contentType":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","sourceType":"contract","carrierId":"123456789","effectiveDate":"2024-01-01","expiryDate":"2024-12-31","description":"Q1 2024 contract rates from carrier"}}}},"responses":{"201":{"description":"Source created successfully with upload URL","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CreateSourceUploadResponse"}}},"example":{"success":true,"data":{"sourceId":"1234567890123456789","uploadUrl":"https://s3.amazonaws.com/bucket/path?signature=...","expiresAt":"2024-01-15T12:30:00.000Z"}}}}},"400":{"description":"Bad request - invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient permissions - requires sources:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/sources/{sourceId}/process":{"post":{"tags":["Sources"],"summary":"Start processing an uploaded source","description":"Initiates processing of a source file after it has been uploaded to the presigned URL.\n\nThe source will be queued for processing and its status will transition through:\n- `pending` → `processing` → `complete` or `failed`\n\nUse GET /sources/{sourceId} to monitor processing status.\nConfigure webhooks to receive notifications when processing completes.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"sourceId","in":"path","required":true,"schema":{"type":"string"},"description":"The source ID returned from the upload endpoint","example":"1234567890123456789"}],"responses":{"200":{"description":"Processing started successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ProcessSourceResponse"}}},"example":{"success":true,"data":{"sourceId":"1234567890123456789","status":"pending","message":"Source queued for processing"}}}}},"400":{"description":"Source not ready for processing (not uploaded yet)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Source not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/sources":{"get":{"tags":["Sources"],"summary":"List all sources","description":"Returns a paginated list of all rate sheet sources for your organization.\n\nSources can be filtered by status and sorted by various fields.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["awaiting_upload","pending","processing","complete","failed"]},"description":"Filter by processing status"},{"name":"carrierId","in":"query","schema":{"type":"string"},"description":"Filter by carrier ID"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100},"description":"Number of results to return"},{"name":"offset","in":"query","schema":{"type":"integer","default":0},"description":"Number of results to skip"}],"responses":{"200":{"description":"Sources retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"sources":{"type":"array","items":{"$ref":"#/components/schemas/ExternalSourceSummary"}},"total":{"type":"integer","description":"Total number of sources matching the filter"}}}}},"example":{"success":true,"data":{"sources":[{"id":"1234567890123456789","filename":"carrier_rates_2024.xlsx","status":"complete","sourceType":"contract","carrierId":"123456789","carrierName":"Maersk","rateCount":1250,"effectiveDate":"2024-01-01","expiryDate":"2024-12-31","createdAt":"2024-01-15T10:00:00.000Z","processedAt":"2024-01-15T10:05:00.000Z"}],"total":1}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/sources/{sourceId}":{"get":{"tags":["Sources"],"summary":"Get source details","description":"Returns detailed information about a specific source, including processing status and any errors.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"sourceId","in":"path","required":true,"schema":{"type":"string"},"description":"The source ID","example":"1234567890123456789"}],"responses":{"200":{"description":"Source details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ExternalSourceDetail"}}},"example":{"success":true,"data":{"id":"1234567890123456789","filename":"carrier_rates_2024.xlsx","status":"complete","sourceType":"contract","carrierId":"123456789","carrierName":"Maersk","rateCount":1250,"effectiveDate":"2024-01-01","expiryDate":"2024-12-31","description":"Q1 2024 contract rates","createdAt":"2024-01-15T10:00:00.000Z","processedAt":"2024-01-15T10:05:00.000Z","error":null}}}}},"404":{"description":"Source not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/query-bank/sources":{"get":{"tags":["Query Bank"],"summary":"List Query Bank sources","description":"Returns all sources currently linked to your Query Bank.\n\nThe Query Bank is a collection of rate sources used when querying for rates.\nOnly sources with status \"complete\" can be added to the Query Bank.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Query Bank sources retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"sources":{"type":"array","items":{"$ref":"#/components/schemas/ExternalQueryBankSource"}}}}}},"example":{"success":true,"data":{"sources":[{"id":"9876543210987654321","sourceId":"1234567890123456789","filename":"carrier_rates_2024.xlsx","carrierId":"123456789","carrierName":"Maersk","effectiveDate":"2024-01-01","expiryDate":"2024-12-31","linkedAt":"2024-01-15T11:00:00.000Z"}]}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Query Bank"],"summary":"Add source to Query Bank","description":"Links a processed source to your Query Bank, making its rates available for querying.\n\n**Requirements**:\n- Source must exist and belong to your organization\n- Source must have status \"complete\"\n- Source cannot already be in the Query Bank\n","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddSourceToQueryBankRequest"},"example":{"sourceId":"1234567890123456789"}}}},"responses":{"201":{"description":"Source added to Query Bank successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/AddSourceToQueryBankResponse"}}},"example":{"success":true,"data":{"sourceId":"1234567890123456789","linkedAt":"2024-01-15T11:00:00.000Z"}}}}},"400":{"description":"Source not eligible (not complete, already in Query Bank)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Source not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/query-bank/sources/{sourceId}":{"delete":{"tags":["Query Bank"],"summary":"Remove source from Query Bank","description":"Unlinks a source from your Query Bank. The source will no longer be included in rate queries.\n\nThis does not delete the source itself - it only removes it from the Query Bank.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"sourceId","in":"path","required":true,"schema":{"type":"string"},"description":"The source ID to remove from Query Bank","example":"1234567890123456789"}],"responses":{"200":{"description":"Source removed from Query Bank successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/RemoveSourceFromQueryBankResponse"}}},"example":{"success":true,"data":{"sourceId":"1234567890123456789","unlinkedAt":"2024-01-15T12:00:00.000Z"}}}}},"404":{"description":"Source not found in Query Bank","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/rates/query":{"post":{"tags":["Rates"],"summary":"Query freight rates","description":"Query freight rates from your Query Bank with flexible location and container filtering.\n\n**Location Filtering**:\n- Use `origins` and `destinations` for door-to-door moves (inland points)\n- Use `loadingPorts` and `dischargePorts` for port-to-port moves\n- Combine both for door-to-port or port-to-door queries\n- Region codes like USWC, USEC are supported for broader searches\n\n**Rate Structure**:\nEach rate includes:\n- Route information with all legs (pre-carriage, main, on-carriage)\n- Container rates with per-leg breakdown\n- Applicable surcharges with container-specific amounts\n\n**Pagination**:\nResults are paginated with a default limit of 100 rates per request.\n","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryBankRateQueryRequest"},"examples":{"port_to_port":{"summary":"Port-to-port query","value":{"loadingPorts":["CNSHA","CNNBO"],"dischargePorts":["USLAX","USLGB"],"containerType":"dry","containerSizes":["40ft","40ft_hc"],"effectiveDate":"2024-01-15","limit":50}},"door_to_door":{"summary":"Door-to-door with regions","value":{"origins":["USWC"],"destinations":["CNSHA","CNNBO"],"containerType":"reefer","carrierCodes":["MAEU","MSCU"]}},"simple":{"summary":"Simple query","value":{"loadingPorts":["CNSHA"],"dischargePorts":["USLAX"]}}}}}},"responses":{"200":{"description":"Rates retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/QueryBankRateQueryResponse"}}},"example":{"success":true,"data":{"rates":[{"id":"rate_abc123","portOfLoading":{"code":"CNSHA","name":"Shanghai","type":"port"},"portOfDischarge":{"code":"USLAX","name":"Los Angeles","type":"port"},"carrierCode":"MAEU","carrierName":"Maersk","effectiveDate":"2024-01-01","expiryDate":"2024-03-31","transitTime":14,"legs":[{"type":"main","origin":{"code":"CNSHA","name":"Shanghai","type":"port"},"destination":{"code":"USLAX","name":"Los Angeles","type":"port"},"mode":"ocean"}],"containerRates":[{"containerType":"dry","containerSize":"40ft","amount":2500,"currency":"USD"},{"containerType":"dry","containerSize":"40ft_hc","amount":2700,"currency":"USD"}],"surcharges":[{"code":"BAF","name":"Bunker Adjustment Factor","applicability":"subject_to","basis":"per_container","containerRates":[{"containerSize":"40ft","amount":150,"currency":"USD"},{"containerSize":"40ft_hc","amount":150,"currency":"USD"}]}],"sourceId":"1234567890123456789","sourceName":"carrier_rates_2024.xlsx"}],"metadata":{"totalRates":1,"sourcesSearched":5,"queryTimeMs":45}}}}}},"400":{"description":"Bad request - invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient permissions - requires rates:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/tariffs/lookup":{"get":{"tags":["Tariffs"],"summary":"Look up duty rates by HS code","description":"Look up import duty rates for a specific HS/HTS code.\n\n**Features**:\n- Supports US, EU, Canada, and Australia tariff schedules\n- Returns MFN rates, preferential rates, and additional duties (Section 301, 232, etc.)\n- Calculates landed cost including customs fees\n- Supports FTA program selection\n- Customer-specific tariff overrides are automatically applied\n\n**HS Code Format**:\n- US: 10-digit HTS code (e.g., \"6209205000\" or \"6209.20.50.00\")\n- Other countries: 4-12 digit HS code\n\n**Additional Duties**:\nFor products subject to Section 232 tariffs (steel/aluminum derivatives),\nyou may need to provide component percentages via `componentValues`.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"hsCode","in":"query","required":true,"schema":{"type":"string"},"description":"HS/HTS code to look up (e.g., \"6209205000\" or \"6209.20.50.00\")","example":"8471609050"},{"name":"originCountry","in":"query","required":true,"schema":{"type":"string","pattern":"^[A-Z]{2}$"},"description":"Origin country code (2-letter ISO)","example":"CN"},{"name":"destinationCountry","in":"query","required":true,"schema":{"type":"string","pattern":"^[A-Z]{2}$"},"description":"Destination country code (2-letter ISO)","example":"US"},{"name":"customsValue","in":"query","required":false,"schema":{"type":"number"},"description":"Customs value for duty calculation","example":10000},{"name":"currency","in":"query","required":false,"schema":{"type":"string","default":"USD"},"description":"Currency code for calculations","example":"USD"},{"name":"entryDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Entry date for historical rate lookup (ISO date)","example":"2024-01-15"},{"name":"dateOfLoading","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Date of loading for historical rate lookup (used if entryDate not provided)"},{"name":"transportMode","in":"query","required":false,"schema":{"type":"string","enum":["ocean","air","land","rail"],"default":"ocean"},"description":"Transport mode for customs fee calculations"},{"name":"componentValues","in":"query","required":false,"schema":{"type":"string"},"description":"JSON object of component values for Section 232 calculations (e.g., '{\"aluminum\": 30}' for 30% aluminum content)\n","example":"{\"aluminum\": 30}"},{"name":"exclusionCodes","in":"query","required":false,"schema":{"type":"string"},"description":"JSON array of importer-claimed codes to apply. Two kinds share this parameter:\n\n- Chapter 99 exclusion codes (e.g. `9903.01.21`).\n- A Chapter 98 provision the entry is claimed under (US destination). Send\n  `9801.00.10` for US-origin goods returning to the US (American goods returned):\n  the base duty becomes 0%, duties that Chapter 98 waives are dropped, and the\n  merchandise processing fee is exempt (19 CFR 24.23(c)(1)(i)). `9802.00.80` and\n  `9802.00.40/.50/.60` reduce the value duty is assessed on and need the deducted\n  value in `componentValues` (`usContentValue` or `repairValue`).\n\nA claim is the importer's attestation; the response reports how it was applied in\n`appliedCh98Provision`. With `originCountry=US` and no Chapter 98 claim, the ordinary\nrate is charged and `warnings` says so. US-origin goods pay the general (MFN)\nrate only: no Chapter 99 additional duty is applied to them.\n","example":"[\"9801.00.10\"]"},{"name":"includeFtaOptions","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]},"description":"Whether to include FTA options in the response"},{"name":"applyFtaProgram","in":"query","required":false,"schema":{"type":"string"},"description":"FTA program code to apply (e.g., 'US_AU_FTA')","example":"US_AU_FTA"},{"name":"weightKg","in":"query","required":false,"schema":{"type":"number"},"description":"Weight in kilograms for per-kg fee calculations"}],"responses":{"200":{"description":"Tariff lookup successful","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"tariffLine":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string","example":"8471.60.90.50"},"description":{"type":"string","example":"Other data processing equipment"},"fullDescription":{"type":"string"},"hs6":{"type":"string","example":"847160"},"uomPrimary":{"type":"string","example":"NO"}}},"applicableRate":{"type":"object","properties":{"regime":{"type":"string","example":"MFN"},"programCode":{"type":"string","example":"US_MFN"},"rateType":{"type":"string","example":"AD_VALOREM"},"adValoremRate":{"type":"number","example":0},"formulaDescription":{"type":"string","example":"Free"}}},"baseRate":{"type":"object","description":"Base MFN/preferential rate without additional duties"},"mfnRate":{"type":"number","description":"MFN rate percentage","example":0},"additionalDuties":{"type":"array","description":"Additional duties (Section 301, 232, etc.)","items":{"type":"object","properties":{"programCode":{"type":"string"},"programName":{"type":"string"},"rate":{"type":"number"},"rateType":{"type":"string"}}}},"calculation":{"type":"object","description":"Duty calculation breakdown (when customsValue provided)","properties":{"dutyAmount":{"type":"number"},"baseDutyAmount":{"type":"number"},"additionalDutyAmount":{"type":"number"},"currency":{"type":"string"},"effectiveRate":{"type":"number"}}},"ftaOptions":{"type":"array","description":"Available FTA programs","items":{"type":"object","properties":{"program":{"type":"string"},"programName":{"type":"string"},"rate":{"type":"number"}}}},"customsFees":{"type":"object","description":"Customs fees breakdown","properties":{"totalFees":{"type":"number"},"fees":{"type":"array","items":{"type":"object"}}}},"landedCost":{"type":"object","description":"Total landed cost breakdown","properties":{"customsValue":{"type":"number"},"totalDuties":{"type":"number"},"totalFees":{"type":"number"},"grandTotal":{"type":"number"}}},"importProhibitions":{"type":"array","description":"Bans on importing these goods from this origin at all — see the\n`ImportProhibition` schema. Omitted when none applies; an absent field\nmeans no ban was found, never that the goods were cleared for entry.\n\nRead this BEFORE the duty figures. An entry carrying an unconditional\nprohibition cannot be made, whatever `calculation` reports alongside it.\n","items":{"$ref":"#/components/schemas/ImportProhibition"}},"appliedCh98Provision":{"type":"object","description":"How a claimed Chapter 98 provision was applied. Present only when one was\nsent in `exclusionCodes`. `unresolved: true` means the claim was NOT\napplied and duty is on the full entered value.\n","properties":{"code":{"type":"string","example":"9801.00.10"},"dutyBasis":{"type":"string","enum":["full_value","foreign_value_add","repair_value","duty_equivalent","ordinary_rate","zero"]},"dutiableValue":{"type":"number"},"unresolved":{"type":"boolean"},"attestations":{"type":"array","items":{"type":"string"}}}},"warnings":{"type":"array","description":"Caveats on this answer (US destination). Omitted when none applies. The\nfigures are correct for the request as sent; a `warning` means they are\nprobably not what the importer will pay.\n\n- `us_origin_no_chapter_98_claim`: origin is the US and no Chapter 98\n  provision is claimed, so the ordinary duty rate was charged. US-origin\n  goods are duty-free only when entered under `9801.00.10`.\n- `us_goods_returned_claim`: `9801.00.10` is claimed; what the claim\n  rests on (proof of US origin, no improvement abroad).\n- `section_232_on_us_goods_returned`: a Section 232 duty on steel,\n  aluminum or copper is still charged on a `9801.00.10` claim for goods\n  declared with a foreign origin, and may not be owed. (US-origin goods\n  carry no additional duty at all.)\n","items":{"type":"object","properties":{"code":{"type":"string","enum":["us_origin_no_chapter_98_claim","us_goods_returned_claim","section_232_on_us_goods_returned"]},"severity":{"type":"string","enum":["warning","info"]},"message":{"type":"string"},"suggestedClaimCode":{"type":"string","description":"A code to send in `exclusionCodes` to act on the warning.","example":"9801.00.10"}}}}}}}},"examples":{"standard_lookup":{"summary":"Ordinary lookup with no additional duties","value":{"success":true,"data":{"tariffLine":{"id":"12345","code":"8471.60.90.50","description":"Other data processing equipment","hs6":"847160","uomPrimary":"NO"},"applicableRate":{"regime":"MFN","programCode":"US_MFN","rateType":"AD_VALOREM","adValoremRate":0,"formulaDescription":"Free"},"mfnRate":0,"additionalDuties":[]}}},"prohibited_import":{"summary":"Goods excluded from importation (Section 338)","description":"Canadian bourbon entered on or after September 29, 2026. The Section 338\nheading 9903.03.12 is ABSENT from `additionalDuties` because the ban replaced\nit rather than stacking with it — `supersededDuties` names it. The duty figures\nthat remain are what an entry made before the effective date owes.\n","value":{"success":true,"data":{"tariffLine":{"id":"67890","code":"2208.30.60.20","description":"Bourbon whiskey, in containers each holding not over 4 liters","hs6":"220830"},"applicableRate":{"regime":"MFN","programCode":"US_MFN","rateType":"AD_VALOREM","adValoremRate":10},"mfnRate":0,"additionalDuties":[{"programCode":"US_301_FORCED_LABOR","htsCode":"9903.05.29","rate":10}],"importProhibitions":[{"description":"Excluded from importation into the United States — Canadian alcoholic beverages (Proclamation of September 8, 2026, section 338(a))","effectiveFrom":"2026-09-29","authority":"section_338","sourceReference":"https://www.whitehouse.gov/presidential-actions/2026/09/excluding-certain-canadian-alcoholic-beverages-from-importation-into-the-united-states-in-response-to-continued-discrimination-against-the-commerce-of-the-united-states-with-respect-to-alcoholic-bever/","supersededDuties":["9903.03.12"]}]}}},"conditionally_prohibited_import":{"summary":"Ban limited to part of the subheading (Section 338)","description":"Canadian beer. Only PACKAGED beer is excluded, which no HS code can establish,\nso the ban is reported as a warning and the Section 338 duty still applies —\n`supersededDuties` is empty and 9903.03.12 remains in `additionalDuties`.\n","value":{"success":true,"data":{"tariffLine":{"id":"67891","code":"2203.00.00.00","description":"Beer made from malt","hs6":"220300"},"applicableRate":{"regime":"MFN","programCode":"US_MFN","rateType":"AD_VALOREM","adValoremRate":60},"mfnRate":0,"additionalDuties":[{"programCode":"US_SECTION_338","htsCode":"9903.03.12","rate":50},{"programCode":"US_301_FORCED_LABOR","htsCode":"9903.05.29","rate":10}],"importProhibitions":[{"description":"Excluded from importation into the United States when packaged in bottles, cans, boxes, kegs or other similar direct-to-consumption containers — Canadian alcoholic beverages (Proclamation of September 8, 2026, section 338(a))","effectiveFrom":"2026-09-29","authority":"section_338","condition":"packaged","supersededDuties":[]}]}}}}}}},"400":{"description":"Bad request - invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missing_hs_code":{"summary":"Missing HS code","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Query parameter \"hsCode\" is required"}}},"invalid_hs_code":{"summary":"Invalid HS code format","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Invalid HS code format. Expected 4-12 digit code."}}}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient permissions - requires tariffs:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Tariff line not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"NOT_FOUND","message":"No tariff line found for HS code 1234567890"}}}}}}}},"/api/v1/external/tariffs/search":{"get":{"tags":["Tariffs"],"summary":"Search tariffs by product description","description":"Search for tariff lines using semantic search on product descriptions.\n\nThis endpoint uses AI-powered semantic search to find relevant HS codes\nbased on natural language product descriptions. Results are ranked by\nrelevance to the search query.\n\nSupply `prefix` to constrain the search to a subtree of the tariff\nschedule. This is useful when the heading is already known and only the\nstatistical suffix is in question — the semantic query then ranks lines\nwithin that subtree instead of across the whole schedule.\n\n**Note**: This endpoint excludes Chapter 99 codes (9903.xx.xx) as they\nare administrative tariff codes, not product classifications.\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"Product description to search for","example":"laptop computer"},{"name":"country","in":"query","required":true,"schema":{"type":"string","pattern":"^[A-Z]{2}$"},"description":"Destination country code (2-letter ISO)","example":"US"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":10},"description":"Maximum number of results (max 50)"},{"name":"entryDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Entry date for historical rate lookup (ISO date)"},{"name":"dateOfLoading","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Date of loading for historical rate lookup"},{"name":"prefix","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{2}(\\.?\\d{2}){0,4}$"},"description":"Anchor results to an HS code prefix. Only tariff lines whose code\nbegins with this prefix are returned; the semantic query still ranks\nthe results within that subtree. Accepts 2-10 digits, dots optional\n(`6109` and `6109.10` are both valid). `q` is still required.\n","example":"6109"}],"responses":{"200":{"description":"Search results retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string","example":"8471.30.01.00"},"description":{"type":"string","example":"Portable automatic data processing machines"},"fullDescription":{"type":"string"},"similarity":{"type":"number","description":"Relevance score (0-1)","example":0.89}}}}}}}},"example":{"success":true,"data":{"results":[{"id":"12345","code":"8471.30.01.00","description":"Portable automatic data processing machines, weighing not more than 10 kg","similarity":0.92},{"id":"12346","code":"8471.41.01.00","description":"Other automatic data processing machines comprising in the same housing at least a CPU and an input and output unit","similarity":0.85}]}}}}},"400":{"description":"Bad request - invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient permissions - requires tariffs:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/tariffs/batch-lookup":{"post":{"tags":["Tariffs"],"summary":"Batch look up duty rates for multiple HS codes, origins, destinations, or entry dates","description":"Look up import duty rates for a batch of items in a single request.\n\nEach item is a self-contained query carrying its own `hsCode`, `originCountry`,\n`destinationCountry`, and (optionally) `entryDate`, so callers can mix and match\nany combination of dimensions in a single request.\n\n**Behaviour**:\n- Items are processed independently; a failure on one item does not abort the batch.\n- Results are returned in request order and matched to each item by the caller-provided `id`.\n- Each item counts toward OAuth rate limits as one request.\n\n**Limits**:\n- Maximum 100 items per request.\n- Item `id` values must be unique within a request.\n\nFor per-item parameter semantics (HS code format, country codes, FTA programs,\ncomponent values, exclusion codes, etc.) see `POST /api/v1/external/tariffs/lookup`.\n","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["id","hsCode","originCountry","destinationCountry"],"properties":{"id":{"type":"string","description":"Caller-provided identifier echoed back in the response. Must be unique within the request.","example":"q1"},"hsCode":{"type":"string","description":"HS/HTS code (e.g., \"6209205000\" or \"6209.20.50.00\")","example":"8471609050"},"originCountry":{"type":"string","pattern":"^[A-Za-z]{2}$","description":"Origin country code (2-letter ISO)","example":"CN"},"destinationCountry":{"type":"string","pattern":"^[A-Za-z]{2}$","description":"Destination country code (2-letter ISO)","example":"US"},"customsValue":{"type":"number","example":10000},"currency":{"type":"string","default":"USD","example":"USD"},"entryDate":{"type":"string","format":"date","description":"Entry date for historical rate lookup (ISO date)","example":"2024-01-15"},"dateOfLoading":{"type":"string","format":"date"},"transportMode":{"type":"string","enum":["ocean","air","land","rail"],"default":"ocean"},"componentValues":{"type":"object","additionalProperties":{"oneOf":[{"type":"number"},{"type":"boolean"}]},"description":"Component values for Section 232 calculations (e.g., {\"aluminum\": 30} for 30% aluminum content)","example":{"aluminum":30}},"exclusionCodes":{"type":"array","items":{"type":"string"},"description":"Importer-claimed codes to apply: Chapter 99 exclusion codes, or a Chapter 98\nprovision such as `9801.00.10` (American goods returned). See the\n`exclusionCodes` parameter of `GET /lookup`.\n","example":["9903.01.21"]},"includeFtaOptions":{"type":"boolean"},"applyFtaProgram":{"type":"string","example":"US_AU_FTA"},"weightKg":{"type":"number"}}}}}},"examples":{"mixed_origins":{"summary":"Same HS code across multiple origins","value":{"items":[{"id":"cn","hsCode":"8471609050","originCountry":"CN","destinationCountry":"US","customsValue":10000},{"id":"mx","hsCode":"8471609050","originCountry":"MX","destinationCountry":"US","customsValue":10000},{"id":"de","hsCode":"8471609050","originCountry":"DE","destinationCountry":"US","customsValue":10000}]}},"mixed_dates":{"summary":"Same HS code/origin across historical entry dates","value":{"items":[{"id":"2024","hsCode":"6209205000","originCountry":"CN","destinationCountry":"US","entryDate":"2024-06-01"},{"id":"2025","hsCode":"6209205000","originCountry":"CN","destinationCountry":"US","entryDate":"2025-06-01"}]}},"mixed_codes":{"summary":"Multiple HS codes from one origin","value":{"items":[{"id":"a","hsCode":"6209205000","originCountry":"CN","destinationCountry":"US"},{"id":"b","hsCode":"8471609050","originCountry":"CN","destinationCountry":"US"}]}}}}}},"responses":{"200":{"description":"Batch lookup processed. Per-item status is reported via the `success` flag on each result.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Caller-provided id from the matching request item"},"success":{"type":"boolean"},"data":{"type":"object","description":"Tariff lookup result (same shape as `GET /api/v1/external/tariffs/lookup`).\nPresent when success is true.\n\nThis includes `importProhibitions`. A batch item can carry a ban\nwhile reporting `success: true` — the lookup succeeded, the goods\njust may not be imported. Check the field per item; do not infer\nadmissibility from the batch status.\n"},"error":{"type":"string","description":"Error message. Present when success is false."},"status":{"type":"integer","description":"HTTP-style status code for the per-item failure (e.g., 400, 404, 500). Present when success is false."}}}}}}}},"example":{"success":true,"data":{"results":[{"id":"cn","success":true,"data":{"tariffLine":{"code":"8471.60.90.50","description":"Other data processing equipment"},"applicableRate":{"regime":"MFN","adValoremRate":0},"additionalDuties":[]}},{"id":"mx","success":false,"error":"No tariff line found for HS code 8471609050","status":404}]}}}}},"400":{"description":"Bad request - request body invalid, items array empty, too many items, or duplicate ids","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"empty_items":{"summary":"Empty items array","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"\"items\" array must not be empty"}}},"too_many_items":{"summary":"Over 100 items","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Maximum 100 items allowed per batch"}}},"duplicate_id":{"summary":"Duplicate item id","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Duplicate item id \"q1\" in request"}}}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient permissions - requires tariffs:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/tms/organizations":{"get":{"tags":["TMS Organizations"],"summary":"List TMS organizations","description":"Retrieve a paginated list of TMS organizations for your customer.","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1},"description":"Page number"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Items per page"},{"name":"source","in":"query","schema":{"type":"string","enum":["cw","gf","lw","ns"]},"description":"Filter by TMS source"},{"name":"type","in":"query","schema":{"type":"string"},"description":"Filter by organization type (e.g. consignee, shipper, carrier)"},{"name":"active","in":"query","schema":{"type":"boolean"},"description":"Filter by active status"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Search by name, code, city, state, country, or email"}],"responses":{"200":{"description":"Organizations retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TmsOrganization"}},"pagination":{"$ref":"#/components/schemas/PaginatedResponse/properties/pagination"}}}}}},"401":{"$ref":"#/components/schemas/UnauthorizedError"},"403":{"description":"Insufficient permissions - requires tms-organizations:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["TMS Organizations"],"summary":"Create a TMS organization","description":"Create a new TMS organization. The combination of (source, code) must be unique.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTmsOrganizationRequest"}}}},"responses":{"201":{"description":"Organization created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/TmsOrganization"}}}}}},"400":{"description":"Invalid request or duplicate organization code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/schemas/UnauthorizedError"},"403":{"description":"Insufficient permissions - requires tms-organizations:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/tms/organizations/{organizationId}":{"get":{"tags":["TMS Organizations"],"summary":"Get a TMS organization","description":"Retrieve a specific TMS organization by ID.","security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/TmsOrganization"}}}}}},"401":{"$ref":"#/components/schemas/UnauthorizedError"},"403":{"description":"Insufficient permissions - requires tms-organizations:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"$ref":"#/components/schemas/NotFoundError"}}},"put":{"tags":["TMS Organizations"],"summary":"Update a TMS organization","description":"Update an existing TMS organization. Only provided fields are updated.","security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTmsOrganizationRequest"}}}},"responses":{"200":{"description":"Organization updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/TmsOrganization"}}}}}},"400":{"description":"Invalid request or duplicate organization code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/schemas/UnauthorizedError"},"403":{"description":"Insufficient permissions - requires tms-organizations:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"$ref":"#/components/schemas/NotFoundError"}}},"delete":{"tags":["TMS Organizations"],"summary":"Delete a TMS organization","description":"Delete a TMS organization by ID.","security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Organization deleted successfully"},"401":{"$ref":"#/components/schemas/UnauthorizedError"},"403":{"description":"Insufficient permissions - requires tms-organizations:delete scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"$ref":"#/components/schemas/NotFoundError"}}}},"/api/v1/external/tms/organizations/import":{"post":{"tags":["TMS Organizations"],"summary":"Import organizations from JSONL file","description":"Upload a JSONL file to bulk import TMS organizations. Each line must be a JSON object\nwith at least `code` and `name` fields. Processing is asynchronous — returns a job ID\nthat can be polled for status. A `bulk_upload.completed` or `bulk_upload.failed` webhook\nis fired when the job finishes, including row-level stats (totalRows, successfulRows, failedRows).\n","security":[{"bearerAuth":[]}],"parameters":[{"name":"source","in":"query","required":true,"schema":{"type":"string","enum":["cw","gf","lw","ns"]},"description":"TMS source for the imported organizations"},{"name":"mode","in":"query","schema":{"type":"string","enum":["replace","merge","skip"],"default":"merge"},"description":"Import mode: `merge` (upsert), `skip` (skip existing), `replace` (delete all then insert)\n"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"JSONL file (max 10MB)"}},"required":["file"]}}}},"responses":{"200":{"description":"Import job queued successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/TmsOrganizationImportResponse"}}}}}},"400":{"description":"Invalid source, mode, or file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/schemas/UnauthorizedError"},"403":{"description":"Insufficient permissions - requires tms-organizations:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/external/tms/organizations/import/{jobId}":{"get":{"tags":["TMS Organizations"],"summary":"Get import job status","description":"Check the status and progress of an organization import job.","security":[{"bearerAuth":[]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Import job status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/TmsOrganizationImportStatus"}}}}}},"401":{"$ref":"#/components/schemas/UnauthorizedError"},"403":{"description":"Insufficient permissions - requires tms-organizations:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"$ref":"#/components/schemas/NotFoundError"}}}}}}