A RESTful JSON API for shipping labels, rate shopping, tracking, and account management. Authenticate with a JWT or API key and start shipping in minutes.
Every request must include a Bearer token in the Authorization header. You can use either a JWT access token (from the login flow) or an API key created in the dashboard.
Authorization: Bearer <jwt_or_api_key>
API keys use the nsk_ prefix and are scoped per-organization. Create one via POST /api-keys.
https://ninjaship.com/api/v1
All endpoint paths below are relative to this base.
Rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining) are included in every response.
Every response is wrapped in a standard envelope.
Success (2xx)
{
"success": true,
"data": { ... }
}Error (4xx / 5xx)
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request data",
"details": { ... }
}
}Common error codes: VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, NOT_FOUND, CONFLICT, INSUFFICIENT_BALANCE, INTERNAL_ERROR
List endpoints accept page and limit query parameters and return a pagination envelope.
GET /shipments?page=2&limit=20
{
"success": true,
"data": {
"items": [ ... ],
"total": 142,
"page": 2,
"limit": 20,
"totalPages": 8
}
}/shipmentsList shipments with pagination. Supports ?page, ?limit, and ?batchId filter./shipmentsCreate a shipment and fetch carrier rates.// POST /shipments
{
"fromAddressId": "uuid", // or inline "fromAddress": { ... }
"toAddress": {
"name": "Jane Doe",
"street1": "456 Oak Ave",
"city": "Austin",
"state": "TX",
"zip": "78701",
"country": "US"
},
"packageType": "package", // envelope | package | flat_rate_*
"weight": { "value": 12, "unit": "oz" },
"dimensions": { "length": 10, "width": 8, "height": 4, "unit": "in" },
"labelFormat": "pdf_4x6", // pdf_4x6 | pdf_8x11 | zpl
"reference": "ORDER-1234",
"signatureConfirmation": false
}
// Response 201
{
"success": true,
"data": { "shipment": { ... }, "rates": [ ... ] }
}/shipments/:idGet shipment details including from/to addresses./shipments/:idDelete a draft or rated shipment (not purchased)./shipments/:id/buyPurchase a label for a rated shipment. Debits your wallet balance.// POST /shipments/:id/buy
{
"rateId": "rate_abc123",
"labelFormat": "pdf_4x6",
"insuranceAmountCents": 0
}
// Response
{
"success": true,
"data": {
"shipment": { ... },
"labelUrl": "https://...",
"trackingNumber": "9400111...",
"trackingPageUrl": "https://..."
}
}/shipments/:id/voidVoid a purchased label and refund your wallet./ratesGet shipping rates for a parcel. Uses your organization's default from-address.// POST /rates
{
"weight": 16,
"weightUnit": "oz",
"length": 12, "width": 8, "height": 4,
"dimensionUnit": "in",
"destination": {
"zip": "90210",
"state": "CA",
"country": "US"
}
}
// Response
{
"success": true,
"data": {
"rates": [
{
"label": "USPS Priority Mail",
"cost": 8.45,
"carrier": "USPS",
"service": "Priority",
"estimatedDays": 2
}
]
}
}/addressesList saved addresses in your address book./addressesCreate a new address.// POST /addresses
{
"name": "Warehouse A",
"street1": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US",
"phone": "555-0100",
"isDefault": true,
"tags": ["warehouse", "east-coast"]
}/addresses/:idGet a single address by ID./addresses/:idUpdate an address. All fields are optional./addresses/:idDelete an address./addresses/validateValidate an address via carrier verification.// POST /addresses/validate
{
"street1": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001"
}
// Response
{
"success": true,
"data": {
"valid": true,
"suggestedAddress": { ... },
"messages": []
}
}/trackingList shipments with tracking status, ordered by last update./tracking/:shipmentIdGet tracking details and event history for a shipment.// Response
{
"success": true,
"data": {
"shipment": {
"id": "uuid",
"status": "in_transit",
"carrier": "USPS",
"trackingNumber": "9400111..."
},
"events": [
{
"status": "in_transit",
"message": "Arrived at facility",
"location": "Memphis, TN",
"carrierTimestamp": "2026-04-01T14:30:00Z"
}
]
}
}/tracking/:shipmentId/refreshManually refresh tracking from the carrier. No request body needed./ordersList orders with pagination. Supports ?status, ?platform, and ?search filters.GET /orders?status=unfulfilled&platform=shopify&search=ORD-100
// Response
{
"success": true,
"data": {
"items": [
{
"id": "uuid",
"orderNumber": "ORD-100",
"platform": "shopify",
"status": "unfulfilled",
"recipientName": "Jane Doe",
"recipientCity": "Austin",
"recipientState": "TX",
"itemCount": 3,
"totalWeightOz": 24
}
],
"total": 1,
"page": 1,
"limit": 20,
"totalPages": 1
}
}/batchesList all batches./batchesCreate a batch from existing shipments.// POST /batches
{
"shipmentIds": ["uuid1", "uuid2", "uuid3"],
"rateSelectionStrategy": "cheapest" // cheapest | fastest | manual
}
// Response 201
{
"success": true,
"data": { "batch": { "id": "uuid", "status": "pending", ... } }
}/batches/:idGet batch details with shipment list and progress.// Response includes progress
{
"success": true,
"data": {
"batch": { ... },
"shipments": [ ... ],
"progress": {
"total": 50,
"completed": 42,
"errors": 1,
"percent": 84
}
}
}/batches/:id/purchasePurchase labels for all shipments in a batch.// POST /batches/:id/purchase
{
"rateSelections": [
{ "shipmentId": "uuid1", "rateId": "rate_abc" },
{ "shipmentId": "uuid2", "rateId": "rate_def" }
]
}/package-presetsList saved package presets./package-presetsCreate a package preset.// POST /package-presets
{
"name": "Small Box",
"length": 8,
"width": 6,
"height": 4,
"weightOz": 16,
"isDefault": false
}/package-presets/:idUpdate a preset. All fields are optional./package-presets/:idDelete a preset.Automation rules apply actions to shipments that match conditions. Rules run in priority order during batch processing.
/automation-rulesList all automation rules./automation-rulesCreate an automation rule.// POST /automation-rules
{
"name": "Priority for heavy packages",
"priority": 10,
"conditionGroups": [
{
"logic": "and",
"conditions": [
{ "field": "weight_oz", "operator": "greater_than", "value": 48 },
{ "field": "destination_state", "operator": "in", "value": ["CA","NY"] }
]
}
],
"actions": [
{ "type": "set_carrier_service", "config": { "carrier": "UPS", "service": "Ground" } },
{ "type": "add_signature", "config": {} }
],
"isActive": true
}Condition fields: weight_oz, zone, destination_country, destination_state, carrier, service, order_value_cents, store_source, package_type, item_name, item_sku, item_count
Action types: set_carrier_service, add_insurance, add_signature, apply_package_preset, tag_shipment, send_email, apply_return_label
/automation-rules/:idUpdate a rule. All fields are optional./automation-rules/:idDelete a rule./pickupsList pickups with pagination. Supports ?shipmentId filter./pickupsCreate a pickup request and get available rates.// POST /pickups
{
"shipmentIds": ["uuid1"],
"addressId": "uuid",
"minDatetime": "2026-04-03T09:00:00Z",
"maxDatetime": "2026-04-03T17:00:00Z",
"instructions": "Ring bell, packages at side door"
}/pickups/:id/cancelCancel a scheduled pickup./api-keysList API keys. Only the key prefix is returned for security./api-keysCreate a new API key. The full key is only returned once.// POST /api-keys
{
"name": "Production integration",
"scopes": ["labels:read", "labels:write", "rates:read", "tracking:read"]
}
// Response 201
{
"success": true,
"data": {
"apiKey": { "id": "uuid", "name": "Production integration", "keyPrefix": "nsk_abc1234..." },
"rawKey": "nsk_abc1234...full_key_here"
}
}Available scopes: labels:read, labels:write, rates:read, tracking:read, addresses:read, addresses:write, balance:read, webhooks:manage
/api-keys/:idRevoke an API key./billing/balanceGet wallet balance and auto-recharge settings.// Response
{
"success": true,
"data": {
"balanceCents": 5000,
"autoRecharge": {
"enabled": true,
"thresholdCents": 1000,
"amountCents": 5000
}
}
}/billing/topupAdd funds to your wallet. Requires a Stripe payment method.// POST /billing/topup
{
"amountCents": 5000,
"paymentMethodId": "pm_..."
}
// Response (immediate success)
{ "success": true, "data": { "status": "succeeded", "balanceCents": 10000 } }
// Response (3D Secure required)
{ "success": true, "data": { "status": "requires_action", "clientSecret": "pi_..._secret_..." } }/billing/payment-methodsList saved payment methods (cards)./billing/payment-methods?id=pm_...Detach a payment method./billing/payment-methods/defaultSet a payment method as the default./billing/transactionsList wallet transactions with pagination./teamList team members in your organization./teamInvite a new team member by email.// POST /team
{
"email": "newuser@example.com",
"role": "member" // owner | admin | member | viewer
}
// Response 201
{
"success": true,
"data": { "member": { "id": "uuid", "email": "newuser@example.com", "role": "member" } }
}/team/:memberIdUpdate a team member's role. Cannot change your own role./team/:memberIdRemove a team member. Cannot remove yourself.Ready to integrate? Create a free account and generate an API key.
Get Started Free