> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alura.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect a shop and sync it

> Connect your Etsy shop in Alura, ask Alura to copy it again, and fix a shop that needs reconnecting

The Your shop API reads your own Etsy shops from the copy Alura keeps of them. You connect a shop once in the Alura app. After that, Alura syncs it on a schedule, and you can ask for an extra sync through the API.

## Connect a shop

You connect shops in Alura, not through the API. In [platform.alura.io](https://platform.alura.io/settings/workspace/etsy-shops), open **Settings**, then **Etsy shops**, and connect the shop with Etsy. The shop then belongs to that workspace. API keys and AI clients of the workspace that have the `workspace:read` scope can read it.

A shop belongs to one workspace at a time. To list the shops a key can read, call `GET /v1/workspace/shops`, or `list_my_shops` in an AI assistant:

```bash cURL theme={null}
curl --fail-with-body -sS https://api.alura.io/v1/workspace/shops \
  -H "Authorization: Bearer $ALURA_API_KEY"
```

```typescript TypeScript theme={null}
interface Shop {
  id: string;
  name: string | null;
  connection: { status: 'ok' | 'reconnect_required'; reconnect_url: string | null };
  sync: { status: string | null; last_synced_at: string | null; next_allowed_at: string | null };
}

const res = await fetch('https://api.alura.io/v1/workspace/shops', { headers: { Authorization: `Bearer ${process.env.ALURA_API_KEY}` } });
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const shops = (await res.json()) as { data: Shop[] };

for (const shop of shops.data) {
  if (shop.connection.status === 'reconnect_required') {
    // Reads still work; syncs wait until the seller reconnects the shop in Alura.
    console.log(`${shop.id} ${shop.name}: reconnect at ${shop.connection.reconnect_url}`);
    continue;
  }
  console.log(`${shop.id} ${shop.name}: last sync ${shop.sync.status ?? 'none'}, next allowed ${shop.sync.next_allowed_at ?? 'now'}`);
}
```

```python Python theme={null}
import json
import os
import urllib.request

request = urllib.request.Request(
    "https://api.alura.io/v1/workspace/shops",
    headers={"Authorization": f"Bearer {os.environ['ALURA_API_KEY']}"},
)
with urllib.request.urlopen(request) as response:
    shops = json.load(response)

for shop in shops["data"]:
    if shop["connection"]["status"] == "reconnect_required":
        # Reads still work; syncs wait until the seller reconnects the shop in Alura.
        print(f"{shop['id']} {shop['name']}: reconnect at {shop['connection']['reconnect_url']}")
        continue
    sync = shop["sync"]
    print(f"{shop['id']} {shop['name']}: last sync {sync['status'] or 'none'}, next allowed {sync['next_allowed_at'] or 'now'}")
```

```json Response (abridged) theme={null}
{
  "data": [
    {
      "id": "22841907",
      "name": "GiftMugStudio",
      "connection": { "status": "ok", "reconnect_url": null },
      "sync": { "status": "queued", "last_synced_at": "2026-10-08T07:00:00.000Z", "next_allowed_at": "2026-10-08T08:00:00.000Z" }
    },
    {},
    {
      "id": "48911633",
      "name": "MugCo",
      "connection": { "status": "reconnect_required", "reconnect_url": "https://platform.alura.io/settings/workspace/etsy-shops" },
      "sync": { "status": "failed" }
    }
  ]
}
```

Each shop's `sync` block says how its latest full sync went, when the last successful one finished, and `next_allowed_at`, the earliest time your plan allows another. A time in the past means now.

## What a sync is

A sync is one run that copies a connected shop's data from Etsy into Alura. It runs in steps: shop settings, listings, orders, reviews, finances and customers. Alura starts syncs on its own schedule, the Alura app starts them, Etsy's order webhooks start smaller ones, and you can start one through the API.

Reads never call Etsy. They return what the last sync stored, with `as_of` saying when that was. A `stale_shops` notice names any shop whose data is more than 7 days old. See [Freshness](/api-reference/freshness).

## Start a sync

Call `POST /v1/workspace/syncs`, or `start_my_sync` in an AI assistant. Send `{"shop_id": "22841907"}` for one shop, or no body for every connected shop. The call returns at once with one outcome per shop:

| `outcome` | What it means |
| - | - |
| `queued` | A new sync is waiting to run. `sync` holds it. |
| `already_running` | A sync of the shop is already queued or running. `sync` holds that one. Asking again doesn't count against the cooldown or the daily cap. |
| `cooldown` | The shop was synced too recently for your plan, or the workspace used its API syncs for the day. `next_allowed_at` says when you can try again. |
| `reconnect_required` | The shop's Etsy connection has ended. `reconnect_url` is where to reconnect it. |
| `unavailable` | Alura couldn't queue the sync. Try again later. |

The answer is `202` when at least one shop is `queued` or `already_running`. When every shop is refused, the call fails and costs nothing:

* `503 service_unavailable` when any shop is `unavailable`;
* otherwise `409 reconnect_required` when every shop needs reconnecting;
* otherwise `429 sync_cooldown`, with `Retry-After` set to the shortest wait.

The error body still lists each shop's outcome in `shops`. A workspace with no connected shop gets `404 not_found`. For what an accepted call costs, see [API credits](/api-reference/api-credits).

A sync takes minutes. Starting one doesn't wait for it. To follow it, read the shop's `sync` block again, or call `GET /v1/workspace/syncs` for the latest sync of each shop and `GET /v1/workspace/syncs/{id}` for one sync. A sync's `status` is `queued`, `running`, `succeeded`, `failed` or `skipped`, and `steps` shows each step. `estimated_ready_at` is `null` when Alura can't estimate it, which for now is always. AI assistants check progress with `get_my_shop`.

## How often you can sync

**Per shop**, your plan sets the least time between two syncs:

| Plan | Least time between syncs |
| - | - |
| Free | 24 hours |
| Basic | 6 hours |
| Growth | 1 hour |
| Professional | 15 minutes |

The time counts from the end of the shop's last completed full sync, whoever started it: Alura's schedule, the app, a webhook or the API. A sync that ended in `failed` counts too, so a failing sync can't be retried in a loop. A `skipped` sync doesn't count.

**Per workspace**, the API starts at most 4 syncs per connected shop per UTC day. A workspace with 3 shops can start 12 API syncs a day, spread over its shops as you like. Only syncs started through the API count. When the workspace reaches the cap, each refused shop gets `cooldown` with `next_allowed_at` at the next UTC midnight, and the response adds a `sync_daily_cap_reached` notice.

## When a shop needs reconnecting

`reconnect_required` means Alura has no working Etsy authorization for the shop. Either Alura holds no token for it, or Etsy refused the token, for example after the seller removed Alura's access on Etsy. Alura can't call Etsy for that shop until it's reconnected.

* **Reads still work.** The shop stays in every list, with `connection.status: reconnect_required` and the data from its last successful sync. Its `as_of` stops moving.
* **Syncs are refused** with the `reconnect_required` outcome, and nothing is queued.
* **To fix it**, open `reconnect_url` (Alura settings, Etsy shops) and connect the shop with Etsy again. Then start a sync.

The API can't reconnect a shop for you. Etsy needs the seller to approve access in a browser.

## Next steps

> **[Coverage](/guides/your-shop-coverage)**
>
> Why a sales number can be null, and when it fills in.

> **[Several shops](/guides/your-shop-multi-shop)**
>
> How reads cover every shop, and when to pass `shop_id`.

> **[Limits](/your-shop/limits)**
>
> What Etsy's API doesn't allow.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.