Quickstart

Verify a sandbox provider key, connect your test partner with a connection code, act for it, and receive your first webhook — in seven steps.

This guide takes you from a new sandbox key to your first call for a partner. You need what Localoy gives you when you become a provider: a sandbox key (ltp_sbx_…) and a test partner account.

1. Set up your environment#

Keep the key and the base URL in environment variables. Every example in this book reads them from there.

Shell
export LOCALOY_BASE_URL="https://…/api/v1/open-network/v1"
export LOCALOY_PROVIDER_KEY="ltp_sbx_…"

The base URL is https://api-host.localoy.app/api/v1/open-network/v1. Sandbox and production share it — the key decides the environment.

2. Verify your key#

Call GET /ping. It needs no scope and no partner.

curl "$LOCALOY_BASE_URL/ping" \
  -H "Authorization: Bearer $LOCALOY_PROVIDER_KEY"
Response · 200
{
  "success": true,
  "data": {
    "ok": true,
    "principal": "TECHNOLOGY_PROVIDER",
    "environment": "SANDBOX",
    "keyPrefix": "ltp_sbx_k7m2q9xa",
    "provider": { "key": "example-pos", "name": "Example POS" }
  }
}

principal confirms that Localoy sees a provider key. There are no scopes: a provider key has none of its own — each connection carries the scopes its partner granted.

3. Get a code from your test partner#

  1. Sign in to the Partner Portal as your test partner.

  2. Open your deep link. It ends with your provider key — provider.key from step 2:

    Deep link
    https://partner.localoy.app/dashboard/open-network/providers?connect=example-pos
  3. Tick Add items to your catalogue, Change and remove its items and Read its items and your bookables — the REGISTRATION, UPDATE and INVENTORY scopes — and generate a connection code.

  4. Copy the code. It is shown once and works for 15 minutes.

Connection code
LCC-7K2M-9QXT-4VBN-H3WP

4. Claim the code#

curl -X POST "$LOCALOY_BASE_URL/connections/claim" \
  -H "Authorization: Bearer $LOCALOY_PROVIDER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "LCC-7K2M-9QXT-4VBN-H3WP" }'
Response · 201
{
  "success": true,
  "data": {
    "id": "cm7c0nn3ct10n00000000001",
    "partnerId": "cm1partnerid000000000000001",
    "partner": { "name": "Sultan's Dine" },
    "status": "ACTIVE",
    "scopes": ["REGISTRATION", "UPDATE", "INVENTORY"],
    "grantedScopes": ["REGISTRATION", "UPDATE", "INVENTORY"],
    "modules": ["EVENT", "DINING"],
    "connectedAt": "2026-09-27T09:14:02.518Z",
    "scopesGrantedAt": "2026-09-27T09:12:40.107Z",
    "pausedAt": null,
    "revokedAt": null,
    "lastCallAt": null
  }
}

Keep the partnerId: it names the partner on every call you make for it.

Shell
export LOCALOY_PARTNER_ID="cm1partnerid000000000000001"

A 404 with connection_code_invalid means the code was mistyped, has expired or was already used. Generate a new one.

5. Write an item for the partner#

Send the partner header with the call. Use a test externalId: the partner has one catalogue for both environments, so a sandbox key writes real items.

cURL
curl -X POST "$LOCALOY_BASE_URL/catalog/items" \
  -H "Authorization: Bearer $LOCALOY_PROVIDER_KEY" \
  -H "X-Localoy-Partner-Id: $LOCALOY_PARTNER_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "test-4471",
    "name": "Kacchi Biryani (full)",
    "priceCents": 45000,
    "stock": 12
  }'
Response · 201
{
  "success": true,
  "message": "Catalog item created",
  "data": {
    "id": "cm1q2w3e4r5t6y7u8i9o0p1b3",
    "externalId": "test-4471",
    "name": "Kacchi Biryani (full)",
    "description": null,
    "priceCents": 45000,
    "currency": "BDT",
    "available": true,
    "stock": 12,
    "metadata": null,
    "localoyRef": null,
    "managedBy": { "type": "TECHNOLOGY_PROVIDER", "key": "example-pos", "name": "Example POS" },
    "createdAt": "2026-09-27T09:16:48.201Z",
    "updatedAt": "2026-09-27T09:16:48.201Z"
  }
}

managedBy marks the item as yours. Read it back with the same header — this needs INVENTORY:

cURL
curl "$LOCALOY_BASE_URL/catalog/items/test-4471" \
  -H "Authorization: Bearer $LOCALOY_PROVIDER_KEY" \
  -H "X-Localoy-Partner-Id: $LOCALOY_PARTNER_ID"

6. Register a webhook endpoint#

You manage your webhook endpoints through the API. Register a sandbox endpoint for your items' events:

cURL
curl -X POST "$LOCALOY_BASE_URL/webhooks" \
  -H "Authorization: Bearer $LOCALOY_PROVIDER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/localoy",
    "environment": "SANDBOX",
    "events": ["catalog.item.created", "catalog.item.updated", "catalog.item.deleted"]
  }'

The 201 response carries the endpoint's id and its signing secret, starting whsec_. Store the secret in your receiver: every delivery is signed with it. See Create an endpoint.

7. Send a test event#

cURL
curl -X POST "$LOCALOY_BASE_URL/webhooks/cm8wh00k0000000000000001/test" \
  -H "Authorization: Bearer $LOCALOY_PROVIDER_KEY"

Localoy sends a signed ping to your endpoint straight away — with partnerId: null, because it is about no partner — and answers with what your endpoint said:

Response · 200
{
  "success": true,
  "message": "Your receiver accepted the test event (200 in 184 ms).",
  "data": {
    "delivery": { "id": "cm8d3l1v3ry0000000000001", "event": "ping", "status": "SUCCEEDED", "…": "…" },
    "ok": true,
    "responseStatus": 200,
    "durationMs": 184,
    "error": null
  }
}

Check that your receiver verifies the signature.

Clean up#

Delete the test item. Your endpoint receives catalog.item.deleted.

cURL
curl -X DELETE "$LOCALOY_BASE_URL/catalog/items/test-4471" \
  -H "Authorization: Bearer $LOCALOY_PROVIDER_KEY" \
  -H "X-Localoy-Partner-Id: $LOCALOY_PARTNER_ID"

Next steps#

  • Connecting partners — put the deep link and the code field into your product.
  • Acting for partners — what you can do for a partner, and what it configures for you.
  • Webhooks — one endpoint for every partner, and the connection events.