# Server API quickstart

> Call the TryYourSize server API from Node or Python. Catalog sync, orders and returns, server-side recommendations.

Source: https://docs.tryyoursize.com/quickstarts/server/

> **For your developer**
>
> **What it does:** Connects our backend to TryYourSize: sync products and garment data, send orders and returns for the size-return report, and read shoppers' sizes server-side. No measurements are ever sent or received.
>
> **Time needed:** A few hours for a first call; a day or two for a full catalog sync.
>
> **What to send them:** A test secret key (sk_test_…) from Studio → Developers → API keys, sent through a password manager, never by email or chat. For a partner, a restricted key (rk_test_…) with only the scopes it needs.

## Conventions

| | |
|---|---|
| Base URL | `https://api.tryyoursize.com` |
| Authentication | `Authorization: Bearer sk_test_…` (or a [restricted key](https://docs.tryyoursize.com/get-started/keys-and-modes.md#key-scopes) `rk_…`) |
| Version | `TYS-Version: 2026-10-25` (see [Versioning](https://docs.tryyoursize.com/guides/versioning.md)) |
| Errors | `{ error, status, code, doc_url, request_id }` plus the `X-Request-ID` header (see [Errors](https://docs.tryyoursize.com/api/errors.md)) |
| Retries | `Idempotency-Key` on POST (see [Idempotency](https://docs.tryyoursize.com/guides/idempotency.md)) |
| Lists | `limit` + `cursor` → `{ data, has_more, next_cursor }` (see [Pagination](https://docs.tryyoursize.com/guides/pagination.md)) |

Catalog paths take a TryYourSize product ID **or your SKU**. The catalog is shared by test and live mode: test answers drafts, live answers published versions.

## Install

**Node.js**

```bash
npm install @tryyoursize/node
```

```ts

const tys = new TryYourSize(process.env.TYS_SECRET_KEY!);
```

**Python**

```bash
pip install tryyoursize
```

```python

tys = tryyoursize.TryYourSize(os.environ["TYS_SECRET_KEY"])
```

**cURL**

```bash
curl https://api.tryyoursize.com/v1/products?limit=5 \
  -H "Authorization: Bearer $TYS_SECRET_KEY" \
  -H "TYS-Version: 2026-10-25"
```

> **Note**
>
> The Node (`@tryyoursize/node`) and Python (`tryyoursize`) libraries are our official server SDKs. They pin `TYS-Version` for you, retry safely with idempotency keys, and follow the API reference one to one; when in doubt, the [API reference](https://docs.tryyoursize.com/api/reference.md) is the source of truth.

## Sync a product

**Node.js**

```ts
const product = await tys.products.create(
  { external_id: "CREW-TSHIRT", name: "Crew T-shirt", category: "tshirt" },
  { idempotencyKey: crypto.randomUUID() },
);

// Your shop's labels for each Studio size: recommendations come back in these labels.
await tys.products.sizeMap.save("CREW-TSHIRT", {
  entries: [
    { studio_size: "S", shop_value: "Small" },
    { studio_size: "M", shop_value: "Medium" },
    { studio_size: "L", shop_value: "Large" },
  ],
});

for await (const p of tys.products.list({ limit: 50 })) {
  console.log(p.id, p.external_id);
}
```

**Python**

```python

product = tys.products.create(
    external_id="CREW-TSHIRT",
    name="Crew T-shirt",
    category="tshirt",
    idempotency_key=str(uuid.uuid4()),
)

tys.products.size_map.save("CREW-TSHIRT", entries=[
    {"studio_size": "S", "shop_value": "Small"},
    {"studio_size": "M", "shop_value": "Medium"},
    {"studio_size": "L", "shop_value": "Large"},
])

for p in tys.products.list(limit=50).auto_paging_iter():
    print(p["id"], p["external_id"])
```

Field names and bodies are in the [API reference](https://docs.tryyoursize.com/api/reference.md).

## Resources

| Node | Python | Endpoint |
|---|---|---|
| `tys.recommendations.create({ handle, products })` | `tys.recommendations.create(...)` | `POST /v1/recommendations` |
| `tys.products.list / create / retrieve / update` | same | `/v1/products`, `/v1/products/{product}` |
| `tys.products.sizeMap.retrieve / save` | `tys.products.size_map.retrieve / save` | `/v1/products/{product}/size_map` |
| `tys.products.garments.list / createDraft` | `tys.products.garments.list / create_draft` | `/v1/products/{product}/garments` |
| `tys.garments.retrieve / updateDraft / publish` | `tys.garments.retrieve / update_draft / publish` | `/v1/garments/{garment_id}` |
| `tys.fitGroups.list / create / retrieve / linkProducts` | `tys.fit_groups.list / create / retrieve / link_products` | `/v1/fit_groups` |
| `tys.orders.create` | `tys.orders.create` | `POST /v1/orders` |
| `tys.returns.create` | `tys.returns.create` | `POST /v1/returns` |
| `tys.auditEvents.list` | `tys.audit_events.list` | `GET /v1/audit_events` |
| `tys.webhooks.constructEvent(rawBody, header, secret)` | `tryyoursize.Webhook.construct_event(payload, sig_header, secret)` | [Webhooks](https://docs.tryyoursize.com/guides/webhooks.md) |

## Errors

**Node.js**

```ts

try {
  await tys.products.retrieve("NO-SUCH-SKU");
} catch (err) {
  if (err instanceof TryYourSizeError) {
    console.error(err.code, err.docUrl, err.requestId);   // "not_found", https://docs…/api/errors/#not_found, …
  }
}
```

**Python**

```python
try:
    tys.products.retrieve("NO-SUCH-SKU")
except tryyoursize.APIError as e:
    print(e.code, e.doc_url, e.request_id)
```

## Next

- [Server-side recommendations](https://docs.tryyoursize.com/guides/server-side-recommendations.md): the shopper's size on your server.
- [Orders and returns](https://docs.tryyoursize.com/guides/outcomes.md): measure size-related returns.
- [Webhooks](https://docs.tryyoursize.com/guides/webhooks.md): `fit.recommended`, `garment.published` and more.
