Help CenterGitHub

Interactive Examples

Learn by doing with step-by-step code examples in multiple languages

Beginner
5 min
Buy Your First Label
Quote, draft, purchase — the three calls that put a real label in your hands
Intermediate
10 min
Track a Shipment
Read a shipment's state, and register a webhook so you are not paying requests to poll
Advanced
15 min
Buy Labels in Bulk
Up to 25 labels in one request — and one rate-limit charge instead of 75
Buy Your First Label
Quote, draft, purchase — the three calls that put a real label in your hands
Beginner
5 min
node >= 18 — fetch is built in, no SDK needed
const API = 'https://atoship.com/api/v1';
const KEY = process.env.ATOSHIP_API_KEY;

async function call(path, body) {
  const res = await fetch(API + path, {
    method: 'POST',
    headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify(body ?? {})
  });
  const data = await res.json();
  // Every error carries error.code (UPPER_SNAKE_CASE). Branch on that —
  // never on the message text, which is free to change.
  if (!res.ok) throw new Error(`${data.error?.code}: ${data.error?.message}`);
  return data;
}

const shipment = {
  from_address: {
    name: 'Warehouse', street1: '417 Montgomery St',
    city: 'San Francisco', state: 'CA', zip: '94104', country: 'US'
  },
  to_address: {
    name: 'Ada Lovelace', street1: '1355 Market St',
    city: 'San Francisco', state: 'CA', zip: '94103', country: 'US'
  },
  parcel: {
    length: 10, width: 8, height: 6,
    weight: 32, weight_unit: 'oz', dimension_unit: 'in'
  }
};

async function buyLabel() {
  // 1. Quote. Rating is free — it spends nothing and commits to nothing.
  const { data: rates } = await call('/rates', shipment);
  if (!rates.length) throw new Error('No rates for this shipment');
  const cheapest = rates.reduce((a, b) => (a.rate <= b.rate ? a : b));
  console.log(`${cheapest.carrier} ${cheapest.service} $${cheapest.rate}`);

  // 2. Create the label as a DRAFT. Still nothing charged.
  const draft = await call('/labels', { ...shipment, rate_id: cheapest.id });
  console.log(draft.id, draft.status);        // 'draft', label_url still null

  // 3. Purchase. THIS is the call that spends money.
  const label = await call(`/labels/${draft.id}/purchase`);
  console.log(label.status, label.tracking_number, label.label_url);
  return label;
}

buyLabel().catch((err) => console.error(err.message));
Next Steps
Ready to implement these examples in your application?