# REST API quickstart

> Get an ActuallyCare API key and make your first authenticated request in about two minutes.

<!-- Source: https://docs.actuallycare.com/api -->

The ActuallyCare REST API lives at `https://api.actuallycare.com/v1`. You authenticate with an API key in the `X-API-Key` header, and every response comes back in the same JSON envelope. Here's the whole loop:

```bash title="cURL"
curl "https://api.actuallycare.com/v1/listings" \
  -H "X-API-Key: YOUR_API_KEY"
```

```javascript title="JavaScript"
const res = await fetch("https://api.actuallycare.com/v1/listings", {
  headers: { "X-API-Key": process.env.ACTUALLYCARE_API_KEY },
});
const body = await res.json();
console.log(`Fetched ${body.data.listings.length} of ${body.data.meta.total} listings`);
```

```python title="Python"
import os
import requests

resp = requests.get(
    "https://api.actuallycare.com/v1/listings",
    headers={"X-API-Key": os.environ["ACTUALLYCARE_API_KEY"]},
)
body = resp.json()
print(f"Fetched {len(body['data']['listings'])} of {body['data']['meta']['total']} listings")
```

```json
{
  "success": true,
  "data": {
    "listings": [
      {
        "id": "0d4f8a9c-3b2e-4f6a-9d1c-7e5b2a8f4c10",
        "address": "456 Oak Ave, Tehachapi, CA 93561",
        "status": "active",
        "list_price": 425000
      }
    ],
    "meta": { "page": 1, "limit": 25, "total": 1, "totalPages": 1, "hasMore": false }
  },
  "timestamp": "2026-06-11T18:24:09.123Z"
}
```

Keep your key in an environment variable — never in source code or anything that ships to a browser. The rest of this page gets you from zero to that response.

## Get an API key

1. Sign in at [app.actuallycare.com](https://app.actuallycare.com) and open **Settings → API Keys** (direct link: [app.actuallycare.com/settings?tab=api](https://app.actuallycare.com/settings?tab=api)). Every user can create their own keys — each key acts as you, with your role's visibility. You need an **active** account: self-registration currently lands on a waitlist, and waitlisted accounts get `403 ACCOUNT_NOT_ACTIVE` on every endpoint (including key creation) until approved.
2. Click to create a key, give it a name that says what it's for ("Reporting script", "Zapier bridge"), choose an expiration, and grant it the scopes it needs — scopes are what give a key access, and a key with no scopes gets `403` on everything.
3. Copy the key immediately. It's a 64-character hex string, shown exactly once — ActuallyCare stores only a hash, and the UI shows just the first 8 and last 4 characters afterward.

Keys can also be created, listed, and revoked over the API itself — see [Authentication](/api/authentication) for the details, including how scopes grant each key its access.

## The response envelope

Every successful response has the same shape: `success` is `true`, `data` holds the result, and `timestamp` is the server time. On list endpoints `data` is an object keyed by the resource (`data.listings`, `data.clients`, …) with pagination metadata at `data.meta` — see [Pagination](/api/pagination). When something goes wrong, `success` flips to `false` and an `error` object explains why — see [Errors](/api/errors).

## What the API covers

The documented REST surface today covers Authentication, API Keys, Contacts, Clients, Leads, Escrows, Listings, Appointments, Webhooks, and Billing. If you need data the REST API doesn't expose, the MCP server covers far more of the platform — see [API vs MCP](/concepts/api-vs-mcp) for how to choose.

There's also a machine-readable OpenAPI spec at `https://api.actuallycare.com/v1/openapi.json` — useful for generating clients or importing endpoints into your own tooling — and an interactive Swagger UI at [api.actuallycare.com/v1/api-docs](https://api.actuallycare.com/v1/api-docs) for trying endpoints in the browser.

## Where next

| You want to | Go to |
| --- | --- |
| Understand API keys, JWTs, and 401 vs 403 | [Authentication](/api/authentication) |
| Page through large result sets | [Pagination](/api/pagination) |
| Handle errors and retries properly | [Errors](/api/errors) |
| Stay under the request limits | [Rate limits](/api/rate-limits) |
| Browse every endpoint, parameter, and field | [API reference](/api/reference) |
| React to changes instead of polling | [Webhooks](/concepts/webhooks) |
