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

# Make your first request

> Connect to the Canary API with curl, JavaScript, or Python

# Make your first request

This path verifies authentication with a read-only request, shows the standard response envelope, and gives you a safe foundation for your first write.

## 1. Create a scoped key

In Canary, open **Settings → API Keys**, create a key, and grant `assets:read`. Copy the value when it appears; Canary shows the full key once.

Store it in an environment variable:

```bash theme={"theme":"github-light"}
export CANARY_API_KEY="sk_live_replace_me"
```

<Warning>
  Test and live keys access the same organization records. Use a dedicated organization or clearly identified fixtures for development writes.
</Warning>

## 2. List one asset

Choose the example for your runtime. Each version calls the production endpoint, sends the Bearer header, and stops on a non-successful response.

<CodeGroup>
  ```bash cURL theme={"theme":"github-light"}
  curl --fail-with-body --silent --show-error \
    "https://api.oncanary.com/v1/assets?limit=1" \
    --header "Authorization: Bearer $CANARY_API_KEY"
  ```

  ```javascript JavaScript theme={"theme":"github-light"}
  const apiKey = process.env.CANARY_API_KEY;
  if (!apiKey) throw new Error('Set CANARY_API_KEY');

  const response = await fetch('https://api.oncanary.com/v1/assets?limit=1', {
    headers: { Authorization: `Bearer ${apiKey}` },
  });

  const body = await response.json();
  if (!response.ok) {
    throw new Error(`${body.code ?? response.status}: ${body.detail ?? 'Request failed'}`);
  }

  console.log(body.data);
  console.log('request', response.headers.get('X-Request-ID'));
  ```

  ```python Python theme={"theme":"github-light"}
  import os
  import requests

  response = requests.get(
      'https://api.oncanary.com/v1/assets?limit=1',
      headers={'Authorization': f"Bearer {os.environ['CANARY_API_KEY']}"},
      timeout=30,
  )
  response.raise_for_status()

  body = response.json()
  print(body['data'])
  print('request', response.headers.get('X-Request-ID'))
  ```
</CodeGroup>

A successful Canary-native list uses this shape:

```json theme={"theme":"github-light"}
{
  "data": [
    {
      "id": "01JAY7C1NQZ5H2R8M4K6T9V3BP",
      "name": "North compressor",
      "asset_type": "equipment",
      "status": "online",
      "criticality": "critical"
    }
  ],
  "meta": {
    "request_id": "req_01JAY8FVDM6CH4R3X9Q2T7K5NP",
    "api_version": "v1",
    "pagination": {
      "has_more": false
    }
  }
}
```

An empty `data` array is also a successful connection.

## 3. Make the first write

Grant `work_orders:write` to a key, then create a work order. The resource IDs for `asset_id`, `location_id`, and assignees are optional.

```bash theme={"theme":"github-light"}
curl --fail-with-body --silent --show-error \
  --request POST "https://api.oncanary.com/v1/work-orders" \
  --header "Authorization: Bearer $CANARY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "title": "Inspect north compressor",
    "description": "Check vibration and oil level",
    "priority": "high"
  }'
```

The response has HTTP `201` and places the created work order in `data`.

## 4. Build for operations

Before running a recurring synchronization:

* Follow the endpoint's [pagination variant](/guides/pagination).
* Retry `429` responses using `Retry-After` and use backoff for transient `5xx` failures.
* Log `X-Request-ID` with every request.
* Plan write retries using the [idempotency guidance](/guides/integration-patterns#write-retries-and-idempotency).

<CardGroup cols={2}>
  <Card title="Resource model" icon="boxes" href="/api-reference/resource-model">
    Choose the right records and relationships.
  </Card>

  <Card title="Endpoint reference" icon="braces" href="/api-reference/overview">
    Browse request fields, filters, scopes, and response schemas.
  </Card>
</CardGroup>
