# Connect a store

> Starts connecting a store. OAuth and store authorization return redirect_url: send the browser there in the same tab; the platform returns to Pidgely, which…

Source: https://docs.pidgely.com/api-reference/commerce/connect-store/

`POST https://api.pidgely.com/commerce/stores`

Starts connecting a store. OAuth and store authorization return `redirect_url`: send the browser there in the same tab; the platform returns to Pidgely, which attaches the store (a flow finished in another browser, or started by an API key, waits to be claimed in the dashboard). Credentials (VTEX) are checked and return the connected `store` (201). Admins only on the dashboard.

**Authorization:** `Bearer pdg_…`. An API key with `full_access`. A `sending_access` key gets `401 restricted_api_key`.

## Body parameters

JSON object.

| Name | Type | Required | Description |
|---|---|---|---|
| `platform` | string | Yes | One of `nuvemshop`, `shopify`, `woocommerce`, `vtex`. |
| `fields` | object (map of string) | No | Fields the platform asks for (`shop`, `store_url`, `account`, `app_key`, `app_token`). |

## Request

This endpoint is not in the [SDKs](https://docs.pidgely.com/sdks/) yet; call it over HTTP.

```bash tab="cURL"
curl -X POST 'https://api.pidgely.com/commerce/stores' \
  -H "Authorization: Bearer $PIDGELY_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "platform": "nuvemshop"
}'
```

## Response

`200 OK`

```json
{
  "redirect_url": "redirect_url",
  "store": {
    "object": "commerce",
    "id": "0199d8a2-6f3c-7c51-9e2a-3b1f0c6d4e21",
    "platform": "nuvemshop",
    "name": "Example",
    "domain": "domain",
    "url": "https://acme.com/webhooks/pidgely",
    "currency": "currency",
    "locale": "locale",
    "status": "pending",
    "status_reason": "status_reason",
    "checkouts_supported": false,
    "sync": {
      "status": "idle",
      "mode": "backfill",
      "resource": "customers",
      "imported": {},
      "error": "error",
      "started_at": "2026-10-12 16:44:41.000000+00",
      "last_synced_at": "2026-10-12 16:44:41.000000+00",
      "next_sync_at": "2026-10-12 16:44:41.000000+00"
    },
    "counts": {
      "customers": 1,
      "products": 1,
      "orders": 1,
      "checkouts": 1
    },
    "email": {
      "from": "Acme <onboarding@acme.com>",
      "reply_to": "reply_to",
      "locale": "locale",
      "effective_locale": "effective_locale"
    },
    "connected_at": "2026-10-12 16:44:41.000000+00",
    "created_at": "2026-10-12 16:44:41.000000+00"
  }
}
```

### Response fields

| Name | Type | Required | Description |
|---|---|---|---|
| `redirect_url` | string | No | Send the browser here (same tab). |
| `store` | object | No | — |
| `store.object` | string | Yes | Object type. One of `store`. |
| `store.id` | string | Yes | Unique id (UUID). UUID. |
| `store.platform` | string | Yes | One of `nuvemshop`, `shopify`, `woocommerce`, `vtex`. |
| `store.name` | string | Yes | Display name. |
| `store.domain` | string | Yes | — |
| `store.url` | string | Yes | Public `https` URL that receives the events. |
| `store.currency` | string | Yes | — |
| `store.locale` | string | Yes | — |
| `store.status` | string | Yes | Current status. One of `pending`, `connected`, `error`, `disconnected`. |
| `store.status_reason` | string | No | — |
| `store.checkouts_supported` | boolean | Yes | — |
| `store.sync` | object | Yes | — |
| `store.sync.status` | string | Yes | Current status. One of `idle`, `queued`, `running`, `failed`. |
| `store.sync.mode` | string | No | One of `backfill`, `reconcile`, `purge`. |
| `store.sync.resource` | string | No | One of `customers`, `products`, `orders`, `checkouts`. |
| `store.sync.imported` | object (map of integer) | Yes | Records read so far by the current or last sync, per resource. |
| `store.sync.error` | string | No | — |
| `store.sync.started_at` | string \| null | Yes | Format: `date-time`. |
| `store.sync.last_synced_at` | string \| null | Yes | Format: `date-time`. |
| `store.sync.next_sync_at` | string \| null | Yes | Format: `date-time`. |
| `store.counts` | object | Yes | — |
| `store.counts.customers` | integer | Yes | — |
| `store.counts.products` | integer | Yes | — |
| `store.counts.orders` | integer | Yes | — |
| `store.counts.checkouts` | integer | Yes | — |
| `store.email` | object | Yes | Email address. |
| `store.email.from` | string | Yes | — |
| `store.email.reply_to` | string | Yes | Reply-To address or list of addresses. |
| `store.email.locale` | string | Yes | — |
| `store.email.effective_locale` | string | Yes | — |
| `store.connected_at` | string \| null | Yes | Format: `date-time`. |
| `store.created_at` | string | Yes | Creation time, `YYYY-MM-DD HH:MM:SS.ffffff+00` (UTC). Format: `date-time`. |

## Errors

Errors have the shape `{"statusCode", "name", "message"}`. See [Errors](https://docs.pidgely.com/errors/) for the full list.

| Status | Name | When |
|---|---|---|
| 401 | `missing_api_key`, `restricted_api_key` | No `Authorization: Bearer` header, or a `sending_access` key called an endpoint that needs `full_access`. |
| 403 | `invalid_api_key`, `validation_error` | The API key is invalid or revoked, or the request is not allowed for this account (unverified domain, plan limit, paused account). |
| 409 | — | Conflict (store_connected_elsewhere, store_connecting, store_not_connected) |
| 422 | `validation_error` | A field is missing or invalid; `message` names it. |
| 429 | `rate_limit_exceeded` | Too many requests per second. Wait for `Retry-After` seconds. |
| 502 | — | The AI service failed or returned an unusable answer (ai_unavailable, ai_busy, ai_timeout, ai_invalid_output) |
