# Nomstash Labels API reference

Base URL: https://api.nomstash.com/v1

Every label has its own code that no other label has. Make as many labels as you
need, attach each one to something in your app by your own {type, id}, and look a
label up by its code when someone scans or types it.

Labels say nothing about how they're printed. Send any labels to `POST /print-files`
with a format, such as an A4 sheet or a roll of stickers, and get a PDF back, over as
many pages as they need. Or queue them for a printer with `POST /print-jobs`: a small
agent beside the printer picks the job up, prints it and says how it went.

Authenticate with an API key from API keys in the Nomstash app
(app.nomstash.com/developers/api-keys), sent as `Authorization: Bearer nsk_…`.
A test key (`nsk_test_…`) and a live key (`nsk_live_…`) each act for their own
account, so test labels never mix with live ones.

Prefer OAuth? Trade the key for an access token that lasts an hour: `POST /oauth/token`
with `grant_type=client_credentials`, the key's id as `client_id` and the key as
`client_secret` (HTTP Basic or form). Send the token the same way, as
`Authorization: Bearer nst_…`. It acts for the same account, with the scopes you asked
for (`labels:read`, `labels:write`), and stops working if the key is revoked. Metadata is
at `/.well-known/oauth-authorization-server`.

Every POST needs an `Idempotency-Key` header. Send the same key on a retry and you
get the first answer back, so a retry never makes labels twice. A key is kept for
24 hours. Errors are `{"error": {"code", "message"}}`.

## Make labels

`POST /labels`

Send `count` to make 1 to 1000 labels, each with a code we choose, in order.

Or send `shortCode` to make one label with 4 characters you chose, for codes you write
by hand or print yourself. It gets your account's prefix in front, such as `3KTA-K4QA`,
and scans and looks up the same as a label we made. Codes use only
`ACDEFHJKLMNPQRSTUVWXYZ234579`, so 0 and O, 1 and I, 8 and B, or 6 and G can't be
mixed up. Each code can be used once in an account.

How you group labels is up to you: tag them with `origin`, or keep the ids in your app.


Parameters:

- `Idempotency-Key` (header, required): Up to 128 characters, unique per request. Send the same one on a retry.

Responses:

- 201: The new labels, in order.
- 400: Something in the request needs changing. The error's message says what.
- 401: No key was sent, or the key is unknown or revoked.
- 403: The key isn't allowed to do this.
- 409: It clashes with the label as it is now, or a request with the same Idempotency-Key is still being handled.
- 422: That Idempotency-Key was already used for a different request.

## Find a label by its code

`GET /labels/{code}`

Takes the full code, such as `3KTA-4K7Q`, or just its last 4 characters. A label in another account is not found.

Parameters:

- `code` (path, required): The full code, such as 3KTA-4K7Q, or its last 4 characters.

Responses:

- 200: The label, and what it's on.
- 404: Nothing with that code or id in this key's account.

## Put a label on something

`POST /labels/{code}/attach`

Attaches the label to something in your app. A label is on one thing at a time; take it off first to move it.

Parameters:

- `code` (path, required): The full code, such as 3KTA-4K7Q, or its last 4 characters.
- `Idempotency-Key` (header, required): Up to 128 characters, unique per request. Send the same one on a retry.

Body:

- `subject` (required): Something in your app, by your own type and id. We store it and hand it back; we never read it.

```json
{
  "subject": {
    "type": "acme.box",
    "id": "box_123"
  }
}
```

Responses:

- 200: The label, now on the subject.
- 400: Something in the request needs changing. The error's message says what.
- 404: Nothing with that code or id in this key's account.
- 409: It clashes with the label as it is now, or a request with the same Idempotency-Key is still being handled.

## Take a label off

`POST /labels/{code}/detach`

Parameters:

- `code` (path, required): The full code, such as 3KTA-4K7Q, or its last 4 characters.
- `Idempotency-Key` (header, required): Up to 128 characters, unique per request. Send the same one on a retry.

Responses:

- 200: The label, now on nothing.
- 404: Nothing with that code or id in this key's account.

## Print labels

`POST /print-files`

Any labels, in a format, as a print-ready PDF over as many pages as they need. Each
label has a QR code and its full code beside it. Labels made with a test key say TEST.

Formats:
- `a4-sheet`: A4 sticker paper with 24 labels, 3 across and 8 down, each 63.5 × 33.9 mm.
  Print at actual size (100%) with "fit to page" turned off.
- `roll-62x29`: 62 × 29 mm labels on a roll, one a page.
- `roll-62-continuous`: 62 mm continuous roll, one label a page, cut every 34 mm.


Body:

- `labels` (required): 
- `format` (required): 
- `link` (optional): Where a scan goes: an https link with `{code}` in it, such as
`https://example.com/l/{code}`. Without one, the QR holds just the code.
- `start` (optional): On a sheet, the first free label on a part-used first page, across then down.

```json
{
  "labels": [
    {
      "code": "3KTA-4K7Q"
    },
    {
      "code": "3KTA-K4QA"
    }
  ],
  "format": "a4-sheet"
}
```

Responses:

- 200: The PDF.
- 400: Something in the request needs changing. The error's message says what.
- 401: No key was sent, or the key is unknown or revoked.
- 403: The key isn't allowed to do this.

## List your printers

`GET /printers`

Responses:

- 200: Your printers.
- 401: No key was sent, or the key is unknown or revoked.

## Add a printer

`POST /printers`

A printer you print to, by what's loaded in it. Its jobs print in that format.

Parameters:

- `Idempotency-Key` (header, required): Up to 128 characters, unique per request. Send the same one on a retry.

Body:

- `stock` (required): 

```json
{
  "stock": "roll-62x29"
}
```

Responses:

- 201: The printer.
- 400: Something in the request needs changing. The error's message says what.
- 403: The key isn't allowed to do this.

## Queue labels for a printer

`POST /print-jobs`

Queues any of your labels for one of your printers. Send each label with the
`printToken` it came with, so only your own labels print. Up to 200 labels a job.
The same Idempotency-Key gives back the same job, so a retry never prints twice.

An agent beside the printer then lists the waiting jobs, fetches each one's PDF,
prints it and says whether it printed. Labels made with a test key say TEST.


Parameters:

- `Idempotency-Key` (header, required): Up to 128 characters, unique per request. Send the same one on a retry.

Body:

- `printerId` (required): 
- `labels` (required): 

Responses:

- 200: The same job again, for a repeated Idempotency-Key.
- 201: The job, waiting for its printer.
- 400: Something in the request needs changing. The error's message says what.
- 403: The key isn't allowed to do this.
- 404: Nothing with that code or id in this key's account.

## List print jobs

`GET /print-jobs`

Your 100 newest jobs, newest first. An agent asks for `status=requested` on its printer to find what to print.

Parameters:

- `printerId` (query): 
- `status` (query): 

Responses:

- 200: The jobs.

## Get a print job

`GET /print-jobs/{printJobId}`

Parameters:

- `printJobId` (path, required): 

Responses:

- 200: The job.
- 404: Nothing with that code or id in this key's account.

## Get a print job's PDF

`GET /print-jobs/{printJobId}/file`

The job's labels as a PDF in its printer's format, for the agent to print at actual size.

Parameters:

- `printJobId` (path, required): 

Responses:

- 200: The PDF.
- 404: Nothing with that code or id in this key's account.

## Say a job printed

`POST /print-jobs/{printJobId}/printed`

Saying it again, or after it failed, changes nothing.

Parameters:

- `printJobId` (path, required): 

Responses:

- 200: The job.
- 404: Nothing with that code or id in this key's account.

## Say a job couldn't print

`POST /print-jobs/{printJobId}/failed`

The first outcome stands.

Parameters:

- `printJobId` (path, required): 

Body:

- `reason` (optional): 

Responses:

- 200: The job.
- 404: Nothing with that code or id in this key's account.

OpenAPI spec: https://nomstash.com/developers/openapi.yaml
