# Getting started

All requests go to one host:

```text
https://api.invoicing.proradius.co
```

Every path starts with `/v1`. Requests and responses are JSON.

## Before you begin

- You need access to **Settings > API** in the PROradius web app. The page is available on the Pro and Enterprise
  plans.
- Some modules are add-ons. Their endpoints answer `403` until the add-on is active on the organization, for
  example service jobs need the **Ticketing System** add-on.

## Create a key

1. Open **Settings > API** and select **Create API Key**.

2. Enter an **API Key Name** that says what the key is for, for example `CRM integration`.

3. Set **Max Calls Per Day**. It is required and must be at least 1.

4. Optional: fill **Allowed IPs**, one address per line or comma-separated. Leave it empty to allow any address.

5. Tick the **Permissions** (abilities) the key needs. Each ability is `module:action`, for example `tickets:create`. Pick only
   what your integration uses. See [Authentication](/concepts/authentication/#abilities) for the full list.

**Caution:** If you select no ability at all, the key is created with full access (`*`). Always choose abilities for
     production keys.

6. Optional: pick **Ticket boards** to limit the key to them. A key without a board list can open every board.

7. Save, then copy the key. It is shown in full only once.

The key is bound to one organization. It never needs an `Organization-Id` header.

## Make your first call

List the first five clients. The key needs `clients:read`.

```bash
curl https://api.invoicing.proradius.co/v1/clients?pageSize=5 \
  -H "Authorization: Bearer $PRORADIUS_API_KEY" \
  -H "Accept: application/json"
```

```js
const res = await fetch('https://api.invoicing.proradius.co/v1/clients?pageSize=5', {
  headers: {
    Authorization: `Bearer ${process.env.PRORADIUS_API_KEY}`,
    Accept: 'application/json',
  },
});
const body = await res.json();
console.log(body.data);
```

```php
$ch = curl_init('https://api.invoicing.proradius.co/v1/clients?pageSize=5');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer '.getenv('PRORADIUS_API_KEY'),
        'Accept: application/json',
    ],
]);
$body = json_decode(curl_exec($ch), true);
print_r($body['data']);
```

```python
import os, requests

res = requests.get(
    "https://api.invoicing.proradius.co/v1/clients",
    params={"pageSize": 5},
    headers={"Authorization": f"Bearer {os.environ['PRORADIUS_API_KEY']}", "Accept": "application/json"},
)
print(res.json()["data"])
```

The response is a page of clients (shortened here):

```json
{
  "data": [
    {
      "id": "b8f2a1c4-7d39-4e52-9a06-1f4c8b3d5e27",
      "username": "demo-client",
      "name": "Demo Client",
      "phone_number": "+961 70 000 000",
      "external_ref": "crm-1001",
      "active": true
    }
  ],
  "links": { "first": "...", "last": "...", "prev": null, "next": "..." },
  "meta": { "current_page": 1, "from": 1, "last_page": 12, "per_page": 5, "to": 5, "total": 58 }
}
```

If you get `401`, the key is missing or wrong. If you get `403`, the key does not have the ability. See
[Errors](/concepts/errors/).

## Make a write request

Write requests send a JSON body with `Content-Type: application/json`. The same pattern works for every module.
This example creates a client; the key needs `clients:create`.

```bash
curl -X POST https://api.invoicing.proradius.co/v1/clients \
  -H "Authorization: Bearer $PRORADIUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Demo Client", "username": "demo-client", "external_ref": "crm-1001" }'
```

A successful create answers `201` with the new resource. A validation problem answers `422` with the field errors.
See [Errors](/concepts/errors/).

## Next steps

- Read the [Concepts](/concepts/authentication/): they apply to every module.
- Open the guide for the module you are integrating, under **Guides** in the sidebar.
- Browse every endpoint in the [API reference](/api/).
- Import the <a href="/downloads/proradius-api.postman_collection.json" download>Postman collection</a> and set its `apiKey` variable.
- Subscribe to [Webhooks](/guides/webhooks/) instead of polling.