---
title: Quickstart
url: /docs/developers/quickstart
---

# Quickstart

Make an API key, see what it can call, and make your first call to the GrowLocal API: listing your business's tables. It takes about five minutes.

## 1. Make a key

In GrowLocal, open the business, go to **Settings**, then **Developers & AI** → **API**, and press **New key**. Give it a name, choose **Read** for the areas whose tables you want to reach, and press **Create key**. Copy the key when it's shown: it starts with `gl_` and you won't see it again. [Make an API key](api-keys.md) covers every choice on that screen.

Keep the key on a server or your own computer. Never put it in a web page, a public repository or a message.

## 2. Find your business's id

Every call goes to your business's own address. Its id is in your dashboard's address while the business is open: the part after `/profiles/`.

In the samples below, replace `gl_YOUR_API_KEY` with your key and `YOUR_BUSINESS_ID` with that id. The JavaScript samples run with Node.js 18 or later as an ES module (save them as a `.mjs` file); the Python samples need the `requests` package.

## 3. See what your key can call

Ask for the catalogue: one entry for each operation your key may call right now.

```curl tabs
curl https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/catalog \
  -H "Authorization: Bearer gl_YOUR_API_KEY"
```

```javascript tabs
const response = await fetch(
  "https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/catalog",
  { headers: { Authorization: "Bearer gl_YOUR_API_KEY" } },
);
const catalogue = await response.json();
for (const entry of catalogue.entries)
  console.log(entry.entryRef, JSON.stringify(entry.target));
```

```python tabs
import requests

response = requests.get(
    "https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/catalog",
    headers={"Authorization": "Bearer gl_YOUR_API_KEY"},
    timeout=30,
)
for entry in response.json()["entries"]:
    print(entry["entryRef"], entry["target"])
```

Each entry names an operation (`entryRef`, such as `data.tables.query@1`) and the `target` you send to call it. Note the `featureId` in the `target` of `data.tables.query@1`: the next step sends it.

## 4. Make your first call

Call [List data tables](reference/data-tables-query.md). Replace `YOUR_FEATURE_ID` with the `featureId` from that operation's catalogue entry; the rest of the `target` is the same for everyone.

```curl tabs
# A new operationId for each new request; the same one to retry it.
curl https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations \
  -H "Authorization: Bearer gl_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "featureId": "YOUR_FEATURE_ID",
    "export": "tables",
    "contractRef": "data.tables.query@1"
  },
  "operationId": "quickstart-list-tables-1",
  "input": {}
}'
```

```javascript tabs
// A new operationId for each new request; the same one to retry it.
const response = await fetch(
  "https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer gl_YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      target: {
        featureId: "YOUR_FEATURE_ID",
        export: "tables",
        contractRef: "data.tables.query@1",
      },
      operationId: "quickstart-list-tables-1",
      input: {},
    }),
  },
);
const receipt = await response.json();
for (const table of receipt.output.tables)
  console.log(table.resourceRef, table.title);
```

```python tabs
import requests

# A new operationId for each new request; the same one to retry it.
response = requests.post(
    "https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
    headers={"Authorization": "Bearer gl_YOUR_API_KEY"},
    json={
        "target": {
            "featureId": "YOUR_FEATURE_ID",
            "export": "tables",
            "contractRef": "data.tables.query@1",
        },
        "operationId": "quickstart-list-tables-1",
        "input": {},
    },
    timeout=30,
)
for table in response.json()["output"]["tables"]:
    print(table["resourceRef"], table["title"])
```

The answer is a receipt with `"status": "applied"` and, in `output.tables`, each table your key can read: its title, its fields and its `resourceRef`, which the row operations need.

## Next

- [Read a list](reference/data-view-source-query.md) reads a table's rows, a page at a time.
- [Change items](reference/data-collection-mutate.md) adds and changes rows; it needs a key with **Act**.
- [Make a call and read the receipt](calls-and-receipts.md) explains every part of a call and its answer.
