<!-- Generated by scripts/build-ai-docs.ts from docs/quickstart.md. Do not edit. -->

# Quickstart

Buy a test label in about five minutes. Test mode uses mock carriers: nothing is charged and nothing
reaches FedEx.

## 1. Get a test key

When sign-up is open, go to `/admin/signup`, enter your company, name, email and a password, and
copy the **test key** it shows (`sk_test_…`). It is shown once. Lost it? Create another under
**More → API keys** (mode: Test), or from the checklist on **Today**.

Sign-up is closed by default; if you see the sign-in page instead, ask an owner for an invitation.

## 2. Buy a label

```sh
export VELOSHIP_KEY=sk_test_…
curl -s https://ship.vprev.dev/v1/shipments \
  -H "Authorization: Bearer $VELOSHIP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "service": "FEDEX_GROUND",
    "parcel": { "weight": 16 },
    "from_address": { "name": "Warehouse", "street1": "100 Main St", "city": "Memphis", "state": "TN", "zip": "38118", "country": "US", "phone": "9015551234" },
    "to_address": { "name": "Jane Doe", "street1": "1 Market St", "city": "San Francisco", "state": "CA", "zip": "94105", "country": "US", "phone": "4155551234" }
  }' | jq -r .label_url
```

The admin's **Today** page fills in your key (right after sign-up) and your saved ship-from address.
With a `service`, one call creates the shipment and buys it. Open the printed `label_url` with the
same `Authorization` header, or find the label under **Shipments** in test mode.

The same call with the TypeScript client (`packages/client`):

```ts
import { VeloShipClient } from "@velopeplabs/ship";

const veloship = new VeloShipClient({ apiKey: process.env.VELOSHIP_KEY!, baseUrl: "https://ship.vprev.dev" });

const shipment = await veloship.shipments.create({
  service: "FEDEX_GROUND",
  parcel: { weight: 16 },
  from_address: { name: "Warehouse", street1: "100 Main St", city: "Memphis", state: "TN", zip: "38118", country: "US", phone: "9015551234" },
  to_address: { name: "Jane Doe", street1: "1 Market St", city: "San Francisco", state: "CA", zip: "94105", country: "US", phone: "4155551234" },
});
console.log(shipment.label_url);
```

## 3. Go live

Live labels need three things, tracked by the **Get started** checklist on **Today**:

1. **A verified email.** With email set up on the server you get a link when you sign up (resend it from
   the checklist). Without it, the operator verifies your account.
2. **A carrier account of your own** under **More → Carriers** (FedEx, UPS or USPS credentials). New
   organizations never ship on the operator's FedEx account.
3. **A subscription, after the free allowance**, when the operator has billing on: live labels are free
   up to a monthly allowance (50 by default), then billed per label. Add a payment method under
   **More → Billing** (owners). Test mode is always free.

Then create a live key (`sk_live_…`) and switch off **Test mode** in the admin. `GET /v1/onboarding`
and `GET /v1/billing` report where you stand.

## AI assistants

Building this with Claude Code, Cursor, Copilot or another assistant? Give it the docs in a form it can read:

- **[`/llms.txt`](https://ship.vprev.dev/llms.txt)** is the index: key facts (base URL, auth, test vs live, ounces, money as strings, idempotency) and links to a markdown version of each guide. **[`/llms-full.txt`](https://ship.vprev.dev/llms-full.txt)** is everything in one file, with a compact endpoint reference.
- **The `veloship` skill** teaches an assistant the integration workflow and the mistakes to avoid: test mode first, an idempotency key on every purchase, reconciling an unknown purchase instead of re-buying, webhook signatures. Install it with:

  ```sh
  mkdir -p .claude/skills/veloship && cd .claude/skills/veloship
  curl -s https://ship.vprev.dev/skills/veloship/files.txt | while read f; do curl -s --create-dirs -o "$f" "https://ship.vprev.dev/skills/veloship/$f"; done
  ```

  Other assistants that read `SKILL.md` folders use the same files in their own skills directory.
- [`/openapi.json`](https://ship.vprev.dev/openapi.json) is the machine-readable spec.

These files are generated from the docs and the API (`bun run docs:ai`), so they match what is on this page.
