# Listings API

> REST endpoints for listings — request and response reference with examples.

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

Property inventory — create, list, update, and remove listings.

Base URL: `https://api.actuallycare.com/v1` · Errors use the [standard envelope](/api/reference#error-responses) — see [Errors](/api/errors).

## List all property listings

```http
GET /v1/listings
```

Returns paginated list of property listings with optional filtering. Default page size 25 (max 100).

### Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `status` | query | enum | No | One of: `active`, `pending`, `sold`, `withdrawn`, `expired` |
| `minPrice` | query | number | No |  |
| `maxPrice` | query | number | No |  |
| `page` | query | integer | No | Page number for pagination · Default: `1` · Min: 1 |
| `limit` | query | integer | No | Number of items per page (default 25; GET /escrows overrides this to 20 at the controller level) · Default: `25` · Max: 100 · Min: 1 |

### Example request

```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": "YOUR_API_KEY",
  },
});
const data = await res.json();
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.actuallycare.com/v1/listings",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = resp.json()
```

### Example response (200)

```json
{
  "success": true,
  "data": {
    "listings": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "mls_number": "ML81992437",
        "address": "456 Oak Ave, Tehachapi, CA 93561",
        "city": "Tehachapi",
        "state": "CA",
        "zip_code": "93561",
        "list_price": 425000,
        "status": "active",
        "property_type": "single_family",
        "bedrooms": 4,
        "bathrooms": 3,
        "square_feet": 2800
      }
    ],
    "meta": {
      "page": 1,
      "limit": 25,
      "total": 87,
      "totalPages": 4,
      "hasMore": true
    }
  },
  "timestamp": "2026-07-01T22:45:03.120Z"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Paginated list — records under data.listings, pagination under data.meta (the envelope also carries data.stats aggregates) |
| `401` | Authentication required |
| `429` | Rate limit exceeded — too many requests in the current window. Wait for the window to reset (see Retry-After) before retrying. |
| `500` | Internal server error |

## Create new listing

```http
POST /v1/listings
```

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `address` | string | Yes | Street address of the property |
| `list_price` | number | Yes | Listing price in USD |
| `property_type` | string | No | Property type (e.g. single_family, condo, townhouse, multi_family, land, commercial) |
| `bedrooms` | integer | No | Number of bedrooms |
| `bathrooms` | number | No | Number of bathrooms |

### Example request

```bash title="cURL"
curl -X POST "https://api.actuallycare.com/v1/listings" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "address": "123 Main St, Bakersfield, CA 93301",
    "list_price": 450000
  }'
```

```javascript title="JavaScript"
const res = await fetch("https://api.actuallycare.com/v1/listings", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "address": "123 Main St, Bakersfield, CA 93301",
    "list_price": 450000
  }),
});
const data = await res.json();
```

```python title="Python"
import requests

resp = requests.post(
    "https://api.actuallycare.com/v1/listings",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "address": "123 Main St, Bakersfield, CA 93301",
        "list_price": 450000
    },
)
data = resp.json()
```

### Example response (201)

```json
{
  "success": true,
  "data": {
    "id": "8c5e2a9f-4d7b-4e3a-b1c8-6f0d9e2a5c74",
    "address": "1847 Cerro Vista Dr, Bakersfield, CA 93306",
    "list_price": 389000,
    "status": "active",
    "property_type": "single_family",
    "bedrooms": 3,
    "bathrooms": 2,
    "version": 1,
    "created_at": "2026-07-01T22:46:18.402Z",
    "updated_at": "2026-07-01T22:46:18.402Z"
  },
  "timestamp": "2026-07-01T22:46:18.410Z"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Listing created |
| `400` | Invalid request data |
| `401` | Authentication required |
| `429` | Rate limit exceeded — too many requests in the current window. Wait for the window to reset (see Retry-After) before retrying. |
| `500` | Internal server error |

## Get listing by ID

```http
GET /v1/listings/{id}
```

### Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Unique identifier (UUID) · Format: uuid |

### Example request

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

```javascript title="JavaScript"
const res = await fetch("https://api.actuallycare.com/v1/listings/:id", {
  headers: {
    "X-API-Key": "YOUR_API_KEY",
  },
});
const data = await res.json();
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.actuallycare.com/v1/listings/:id",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = resp.json()
```

### Example response (200)

```json
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "mls_number": "ML81992437",
    "address": "456 Oak Ave, Tehachapi, CA 93561",
    "city": "Tehachapi",
    "state": "CA",
    "zip_code": "93561",
    "list_price": 425000,
    "status": "active",
    "property_type": "single_family",
    "bedrooms": 4,
    "bathrooms": 3,
    "square_feet": 2800,
    "year_built": 2010,
    "version": 3
  },
  "timestamp": "2026-07-01T22:47:00.115Z"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Listing found |
| `401` | Authentication required |
| `404` | Resource not found |
| `429` | Rate limit exceeded — too many requests in the current window. Wait for the window to reset (see Retry-After) before retrying. |
| `500` | Internal server error |

## Update listing

```http
PUT /v1/listings/{id}
```

### Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Unique identifier (UUID) · Format: uuid |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `list_price` | number | No | Listing price in USD |
| `status` | string | No | Listing status (active, pending, sold, withdrawn, expired) |
| `version` | integer | No | Current record version for optimistic locking |

### Example request

```bash title="cURL"
curl -X PUT "https://api.actuallycare.com/v1/listings/:id" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "list_price": 450000,
    "status": "your-status",
    "version": 3
  }'
```

```javascript title="JavaScript"
const res = await fetch("https://api.actuallycare.com/v1/listings/:id", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "list_price": 450000,
    "status": "your-status",
    "version": 3
  }),
});
const data = await res.json();
```

```python title="Python"
import requests

resp = requests.put(
    "https://api.actuallycare.com/v1/listings/:id",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "list_price": 450000,
        "status": "your-status",
        "version": 3
    },
)
data = resp.json()
```

### Example response (200)

```json
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "mls_number": "ML123456",
    "address": "456 Oak Ave, Tehachapi, CA 93561",
    "city": "Tehachapi",
    "state": "CA",
    "zip_code": "93561",
    "list_price": 425000,
    "status": "active",
    "property_type": "single_family",
    "bedrooms": 4,
    "bathrooms": 3,
    "square_feet": 2800,
    "lot_size": 0.5,
    "year_built": 2010,
    "description": "example description",
    "listing_date": "2026-07-15",
    "expiration_date": "2026-07-15",
    "photos": [
      "example photos"
    ],
    "virtual_tour_url": "example virtual tour url",
    "showing_instructions": "example showing instructions",
    "days_on_market": 1,
    "price_per_sqft": 1800,
    "version": 1,
    "created_at": "2026-07-15T14:32:10.000Z",
    "updated_at": "2026-07-15T14:32:10.000Z"
  },
  "timestamp": "2026-07-15T14:32:10.000Z"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Listing updated |
| `400` | Invalid request data |
| `401` | Authentication required |
| `404` | Resource not found |
| `429` | Rate limit exceeded — too many requests in the current window. Wait for the window to reset (see Retry-After) before retrying. |
| `500` | Internal server error |

## Delete listing

```http
DELETE /v1/listings/{id}
```

Permanently deletes a listing (hard delete — only allowed after the listing has been archived)

### Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Unique identifier (UUID) · Format: uuid |

### Example request

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

```javascript title="JavaScript"
const res = await fetch("https://api.actuallycare.com/v1/listings/:id", {
  method: "DELETE",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
  },
});
const data = await res.json();
```

```python title="Python"
import requests

resp = requests.delete(
    "https://api.actuallycare.com/v1/listings/:id",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = resp.json()
```

### Example response (200)

```json
{
  "success": true,
  "data": {},
  "timestamp": "2026-07-15T14:32:10.000Z"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Listing deleted |
| `401` | Authentication required |
| `404` | Resource not found |
| `429` | Rate limit exceeded — too many requests in the current window. Wait for the window to reset (see Retry-After) before retrying. |
| `500` | Internal server error |
