# GearDex Studio API — complete documentation

- [GearDex API + MCP](https://www.geardex.app/api-docs/overview.md): Build photography inventory, shoot planning, maintenance, and agent workflows with the GearDex Studio API and MCP adapter.
- [Getting started](https://www.geardex.app/api-docs/getting-started.md): Get started with GearDex Studio API keys, first request, and key security practices.
- [What can you build?](https://www.geardex.app/api-docs/what-can-you-build.md): Build ideas, sample API queries, and response payloads for GearDex Studio users.
- [Authentication](https://www.geardex.app/api-docs/authentication.md): Create GearDex Studio API keys and authenticate server-side requests with scoped bearer tokens.
- [Scopes](https://www.geardex.app/api-docs/scopes.md): Choose least-privilege read and write scopes for GearDex Studio API integrations.
- [Endpoints](https://www.geardex.app/api-docs/endpoints.md): Reference GearDex Studio API endpoints for gear, shoots, maintenance, lending, documents, analytics, and profiles.
- [Responses and errors](https://www.geardex.app/api-docs/errors.md): Understand GearDex Studio API response bodies, status codes, authentication failures, validation errors, and safe retry behavior.
- [Rate limits](https://www.geardex.app/api-docs/rate-limits.md): Design GearDex Studio API integrations around per-key request windows, 429 responses, Retry-After, and safe backoff.
- [Webhooks](https://www.geardex.app/api-docs/webhooks.md): Receive and verify signed GearDex Studio webhook events for gear, shoots, maintenance, and lending changes.
- [OpenAPI specification](https://www.geardex.app/api-docs/openapi.md): Download the live GearDex Studio OpenAPI specification for SDK generation, API clients, and contract tooling.
- [Audit activity](https://www.geardex.app/api-docs/audit-logs.md): Review GearDex Studio API key actions, request routes, status codes, auth results, IP addresses, and client details.
- [MCP adapter](https://www.geardex.app/api-docs/mcp-adapter.md): Connect the GearDex MCP adapter to your Studio API keys and expose scoped tools to Claude Desktop, Cursor, and custom MCP hosts.

---

# GearDex API + MCP

Source: https://www.geardex.app/api-docs

API access requires the GearDex Studio plan and a scoped Studio API key.

Use the Studio API directly or connect through MCP for controlled, tool-based workflows across your photography operation.

[Get started](https://www.geardex.app/api-docs/getting-started) [Endpoint reference](https://www.geardex.app/api-docs/endpoints)

endpoints

35

scopes

15

requests / min

120

**Request**

```bash
curl "https://www.geardex.app/api/studio-agent/v1/gear?type=camera&limit=3" \
  -H "Authorization: Bearer gdx_live_your_key_here"
```

**200 OK**

```json
{
  "data": [
    { "brand": "Sony", "model": "A7S III" },
    { "brand": "Canon", "model": "R5 C" }
  ],
  "pagination": {
    "limit": 3, "returned": 2, "total": 8
  }
}
```

## Overview

GearDex gives Studio integrations scoped access to photography inventory, shoot plans, maintenance records, documents, analytics, and profile data. Trusted services can also create and update gear, shoots, and maintenance work when their key includes write access.

Use direct HTTP calls when you control the client. Use the [MCP adapter](https://www.geardex.app/api-docs/mcp-adapter) when an agent host should work through named tools instead of composing raw requests.

Base URL

`https://www.geardex.app/api/studio-agent/v1`

## Choose a path

Start with the workflow closest to what you are building.

[Make an authenticated requestCreate a scoped Studio key and retrieve your first gear records.](https://www.geardex.app/api-docs/getting-started) [Explore the endpoint referenceWork with gear, shoots, maintenance, documents, analytics, and profile data.](https://www.geardex.app/api-docs/endpoints) [Connect through MCPExpose controlled GearDex tools to compatible agent hosts and automations.](https://www.geardex.app/api-docs/mcp-adapter) [React to studio changesVerify signed webhook events and synchronize downstream workflows.](https://www.geardex.app/api-docs/webhooks)

## Core resources

The v1 surface follows the main parts of a GearDex studio workspace.

**GearDex Studio API resources**

| Resource | Access | Covers |
| --- | --- | --- |
| `Gear` | `read + write` | Inventory records for cameras, lenses, accessories, filters, and drones. |
| `Shoots` | `read + write` | Production plans, dates, locations, status, notes, and completion progress. |
| `Maintenance` | `read + write` | Service schedules, repair status, providers, cost, and owned gear references. |
| `Documents` | `read` | Receipt, warranty, insurance, and manual metadata with timeline filters. |
| `Analytics` | `read` | Portfolio-level inventory and operational summary counts. |
| `Profile` | `read` | Account and Studio profile metadata for connected workflows. |

## Reference

- [AuthenticationBearer keys and request authentication.](https://www.geardex.app/api-docs/authentication)
- [ScopesRead and write permissions for Studio keys.](https://www.geardex.app/api-docs/scopes)
- [EndpointsGear, shoots, maintenance, documents, and analytics.](https://www.geardex.app/api-docs/endpoints)
- [Responses and errorsStatus codes, error bodies, and safe retries.](https://www.geardex.app/api-docs/errors)
- [Rate limitsRequest windows, throttling, and backoff.](https://www.geardex.app/api-docs/rate-limits)
- [WebhooksSigned event delivery and verification.](https://www.geardex.app/api-docs/webhooks)
- [OpenAPI specMachine-readable schemas for SDKs and tools.](https://www.geardex.app/api-docs/openapi)
- [Audit activityKey management and API request history.](https://www.geardex.app/api-docs/audit-logs)

## What you can build

Dashboards, assistants, reporting, and trusted planning automations. A few starting points:

Pre-shoot readiness assistant

Compare upcoming shoots with available gear and flag incomplete prep before call time.

Weekly inventory digest

Summarize gear by type, identify aging equipment, and send a focused Monday review.

Client-facing gear lists

Turn filtered inventory queries into clean equipment summaries for pitches and pre-production.

Shoot pipeline board

Build an external status view from planning, confirmed, completed, and cancelled shoots.

Warranty watchdog

Monitor document warranty metadata and trigger reminders before coverage expires.

 [See all ideas with sample payloads](https://www.geardex.app/api-docs/what-can-you-build)

---

# Getting started

Source: https://www.geardex.app/api-docs/getting-started

API access requires the GearDex Studio plan and a scoped Studio API key.

Set up your first Studio API integration in minutes with secure key management defaults.

## Prerequisites

- [Studio subscription](https://www.geardex.app/pricing) with API access enabled
- An external agent runtime (Claude Desktop, Cursor, custom app, etc.)
- Secure environment variable storage for credentials

## Create an API key

1. [Sign in](https://www.geardex.app/signin) and open **Settings**, then **API & Agents**.
2. Click `Create API key`.
3. Pick only required [scopes](https://www.geardex.app/api-docs/scopes). Available: `gear:read`, `gear:write`, `shoots:read`, `shoots:write`, `maintenance:read`, `maintenance:write`, `documents:read`, `analytics:read`, `profile:read`, `loans:read`, `loans:write`, `bookings:read`, `bookings:write`, `money:read`, `money:write`.
4. Set an expiration window and save the key securely.

## First request

Send the key as a bearer token. This returns your three most recent gear records. See [Authentication](https://www.geardex.app/api-docs/authentication) for a JavaScript version.

**Request (cURL)**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/gear?limit=3" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

## Secure storage

Keep keys server-side

Never place API keys in frontend bundles or checked-in code. Store keys in environment variables, secret managers, or encrypted runtime settings.

**.env example**

```env
GEARDEX_BASE_URL=https://www.geardex.app
GEARDEX_STUDIO_API_KEY=gdx_live_your_key_here
```

## Rotation and revocation

Rotate keys proactively and revoke immediately if an integration is no longer needed or you suspect exposure.

- Use one key per integration.
- Prefer expiring keys over permanent keys.
- Review API [activity logs](https://www.geardex.app/api-docs/audit-logs) in Settings regularly.

---

# What can you build?

Source: https://www.geardex.app/api-docs/what-can-you-build

API access requires the GearDex Studio plan and a scoped Studio API key.

Use these practical ideas, sample requests, and realistic responses to design your first GearDex-powered agent workflows.

## Build ideas

The Studio API is scoped by design in v1, which makes it useful for dashboards, assistants, reporting, and trusted planning automations that can create, correct, or retire gear, shoot, and maintenance records when granted `gear:write`, `shoots:write`, or `maintenance:write`.

Pre-shoot readiness assistant

Compare upcoming shoots with available gear and flag incomplete prep before call time.

Weekly inventory digest

Summarize gear by type, identify aging equipment, and send a focused Monday review.

Client-facing gear lists

Turn filtered inventory queries into clean equipment summaries for pitches and pre-production.

Shoot pipeline board

Build an external status view from planning, confirmed, completed, and cancelled shoots.

Warranty watchdog

Monitor document warranty metadata and trigger reminders before coverage expires.

Service queue automator

Create service records from inspections and keep repair status synchronized through webhooks.

Lending desk bot

Check gear out and in from Slack, and post overdue loans and new flags from webhooks.

Executive snapshot bot

Publish a concise daily inventory and operations brief from the analytics endpoint.

 [Make your first request](https://www.geardex.app/api-docs/getting-started)

## Sample gear queries

Use `/gear` for filtered inventory slices. Start with narrow payloads and paginate outward.

`GET` `/gear?type=camera&limit=3`  `gear:read`

**Request (cURL)**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/gear?type=camera&limit=3" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

**Response**

```json
{
  "data": [
    {
      "id": "f0a9f6d7-9ab7-4f3c-ae9f-f4b0de2a19b2",
      "gear_type": "camera",
      "brand": "Sony",
      "model": "A7S III",
      "status": "ready",
      "condition": "excellent",
      "purchase_price": 3499,
      "purchase_date": "2024-03-12",
      "created_at": "2025-12-08T14:11:22.801Z",
      "updated_at": "2026-02-01T09:43:10.104Z"
    },
    {
      "id": "3a94ef81-cfc8-4623-ae24-0f8a42d0f115",
      "gear_type": "camera",
      "brand": "Canon",
      "model": "R5 C",
      "status": "ready",
      "condition": "good",
      "purchase_price": 4299,
      "purchase_date": "2023-11-21",
      "created_at": "2025-11-19T09:27:15.125Z",
      "updated_at": "2026-01-25T17:06:44.217Z"
    }
  ],
  "pagination": {
    "type": "camera",
    "limit": 3,
    "offset": 0,
    "returned": 2,
    "total": 8
  }
}
```

## Additional endpoints

You can combine the same API key with additional scopes to build richer agent workflows beyond inventory and shoots.

**Request (cURL): analytics summary**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/analytics" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

**Response: analytics summary**

```json
{
  "data": {
    "generated_at": "2026-02-16T23:30:02.512Z",
    "inventory": {
      "total_items": 43,
      "by_type": {
        "camera": 8,
        "lens": 17,
        "accessory": 10,
        "filter": 6,
        "drone": 2
      }
    },
    "shoots": {
      "total": 14,
      "by_status": {
        "planning": 4,
        "confirmed": 6,
        "completed": 3,
        "cancelled": 1
      }
    },
    "maintenance": {
      "total": 19,
      "by_status": {
        "scheduled": 3,
        "in_progress": 2,
        "completed": 13,
        "cancelled": 1
      }
    },
    "documents": {
      "total": 28,
      "by_type": {
        "receipt": 14,
        "warranty": 8,
        "insurance": 5,
        "user_manual": 1
      }
    }
  }
}
```

**Request (cURL): profile**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/profile" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

**Response: profile**

```json
{
  "data": {
    "profile": {
      "id": "2f71f0dd-4a5a-4ea3-b44f-7c4f1c3f7df4",
      "full_name": "GearDex Studio",
      "email": "studio@example.com",
      "city": "Los Angeles",
      "state": "CA",
      "country": "US",
      "currency": "USD",
      "timezone": "America/Los_Angeles",
      "subscription_tier": "studio",
      "subscription_status": "active",
      "created_at": "2025-08-14T12:12:12.920Z",
      "updated_at": "2026-02-10T08:44:01.145Z"
    },
    "studioProfile": {
      "business_name": "Northline Productions LLC",
      "business_email": "ops@northlinepro.com",
      "business_phone": "+1-555-301-7731",
      "default_currency": "USD",
      "default_payment_terms": "Net 30",
      "default_tax_rate": 8.25,
      "created_at": "2025-10-02T16:18:33.844Z",
      "updated_at": "2026-01-30T13:02:17.291Z"
    }
  }
}
```

## Sample shoot queries

Use `/shoots` for timeline and status planning. Pair `status` with date windows to create scheduling views, or grant `shoots:write` to trusted tools that draft new plans, correct timing or status, or remove cancelled plans.

The same pattern applies elsewhere: `gear:write` allows `POST /gear`, `PATCH /gear/{id}`, and `DELETE /gear/{id}` for trusted inventory sync, and `maintenance:write` allows the matching `/maintenance` routes for ops tools that schedule, complete, or clean up service records.

`GET` `/shoots?status=confirmed&fromDate=2026-02-16&toDate=2026-03-16&limit=5`  `shoots:read`

**Request (cURL)**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/shoots?status=confirmed&fromDate=2026-02-16&toDate=2026-03-16&limit=5" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

**Response**

```json
{
  "data": [
    {
      "id": "39b0b677-7d24-435f-a8df-c10c0c2b4b62",
      "title": "Spring Editorial Campaign",
      "client_name": "Northline Apparel",
      "shoot_date": "2026-02-22",
      "shoot_time": "09:00",
      "location": "Los Angeles, CA",
      "status": "confirmed",
      "completion_progress": 68,
      "created_at": "2026-01-12T13:24:55.454Z",
      "updated_at": "2026-02-14T19:05:22.329Z"
    },
    {
      "id": "f3e2c26e-c7c8-4838-a127-d9e13f52d100",
      "title": "Product Launch Sizzle",
      "client_name": "Apex Audio",
      "shoot_date": "2026-03-02",
      "shoot_time": "14:30",
      "location": "Austin, TX",
      "status": "confirmed",
      "completion_progress": 52,
      "created_at": "2026-01-29T16:44:11.092Z",
      "updated_at": "2026-02-15T08:09:13.608Z"
    }
  ],
  "pagination": {
    "limit": 5,
    "offset": 0,
    "returned": 2,
    "total": 2
  },
  "filters": {
    "status": "confirmed",
    "fromDate": "2026-02-16",
    "toDate": "2026-03-16"
  }
}
```

**Create shoot (cURL)**

```bash
curl -X POST "https://www.geardex.app/api/studio-agent/v1/shoots" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "New Product Editorial",
    "client_name": "Apex Audio",
    "shoot_date": "2026-03-18",
    "shoot_time": "10:00",
    "locations": ["Studio A", "Rooftop"]
  }'
```

**Update shoot (cURL)**

```bash
curl -X PATCH "https://www.geardex.app/api/studio-agent/v1/shoots/shoot_uuid" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "updates": {
      "shoot_time": "11:30",
      "status": "confirmed",
      "completion_progress": 72
    }
  }'
```

## Sample maintenance writes

Use `/maintenance` to keep service work connected to the exact owned gear item it affects. Write calls validate both the maintenance subscription feature and the gear reference.

`POST` `/maintenance`  `maintenance:write`

**Create maintenance (cURL)**

```bash
curl -X POST "https://www.geardex.app/api/studio-agent/v1/maintenance" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "item_type": "camera",
    "item_id": "gear_item_uuid",
    "service_type": "Sensor cleaning",
    "service_date": "2026-03-21",
    "service_provider": "Local camera shop",
    "status": "scheduled"
  }'
```

**Complete maintenance (cURL)**

```bash
curl -X PATCH "https://www.geardex.app/api/studio-agent/v1/maintenance/maintenance_uuid" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "updates": {
      "status": "completed",
      "cost": 149,
      "notes": "Sensor cleaned and body inspected"
    }
  }'
```

## Agent playbooks

These are high-signal prompts you can hand to an AI agent once API auth is configured.

`01` 

Show all confirmed shoots in the next 30 days and list the top 10 camera bodies we can pull for each.

`02` 

Find gear with model or brand matching "Sony", group by type, and output a production prep checklist.

`03` 

Create a weekly summary: total gear count by type plus shoots by status for the current month.

`04` 

Return shoots in planning status with completion progress below 40 so our producer can prioritize follow-up.

`05` 

Create maintenance records for gear flagged in today's inspection notes, then show me what changed.

`06` 

List every open loan that is overdue, grouped by borrower, with the items each person still has.

Prefer named tools over raw requests? Run the same prompts through the [MCP adapter](https://www.geardex.app/api-docs/mcp-adapter).

## Next steps

1. Start with one key and minimum [scopes](https://www.geardex.app/api-docs/scopes), then test your agent flow with `limit=3` queries.
2. Build one narrow workflow first (for example: upcoming shoot digest) before expanding to multi-step agents.
3. Use [audit logs](https://www.geardex.app/api-docs/audit-logs) in Settings to validate exactly which requests your agent is making.

---

# Authentication

Source: https://www.geardex.app/api-docs/authentication

API access requires the GearDex Studio plan and a scoped Studio API key.

Every Studio API request uses a scoped bearer key tied to one GearDex account and integration.

## Bearer authentication

Send your key in the `Authorization` header on every request. GearDex validates the key, subscription access, expiration, revocation status, rate limit, requested scope, and resource ownership before returning Studio data.

Server-side only

A Studio API key is a secret. Do not place it in a browser bundle, mobile binary, public repository, client-visible environment variable, or analytics payload.

## Create a key

1. [Sign in](https://www.geardex.app/signin) and open **Settings**, then **API & Agents**.
2. Choose a name that identifies the service using the key.
3. Select the minimum required [scopes](https://www.geardex.app/api-docs/scopes).
4. Set an expiration date appropriate for the integration.
5. Copy the key once and store it in your secret manager.

Key format

Live Studio keys begin with  `gdx_live_` . GearDex stores a secure hash rather than the original secret.

## Request example

The bearer token belongs in the header, not in a query string or JSON body.

**Request (cURL)**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/gear?limit=3" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

**Request (JavaScript)**

```js
const response = await fetch("https://www.geardex.app/api/studio-agent/v1/gear?limit=3", {
  headers: {
    Authorization: `Bearer ${process.env.GEARDEX_STUDIO_API_KEY}`,
    Accept: "application/json",
  },
})

if (!response.ok) {
  throw new Error(`GearDex request failed: ${response.status}`)
}

const payload = await response.json()
```

## Key lifecycle

- Use one key per application, agent host, or automation.
- Prefer short, explicit expiration windows.
- Rotate secrets without changing the integration's scope model.
- Revoke a key immediately when a machine or service is retired.
- Review [activity logs](https://www.geardex.app/api-docs/audit-logs) for unexpected endpoints or request volume.

## Authentication errors

**GearDex authentication error responses**

| Status and code | Kind | Meaning |
| --- | --- | --- |
| `401 missing_authorization` | authentication | The request did not include a Bearer authorization header. |
| `401 key_not_found` | authentication | The key is invalid, unknown, or no longer available. |
| `401 key_revoked` | authentication | The Studio owner revoked this integration key. |
| `401 key_expired` | authentication | The key passed its configured expiration date. |
| `403 insufficient_scope` | authorization | The key is valid but cannot perform the requested operation. |
| `429 rate_limited` | rate limit | Back off and respect the Retry-After response header. |

The full list of codes lives in [Responses and errors](https://www.geardex.app/api-docs/errors).

---

# Scopes

Source: https://www.geardex.app/api-docs/scopes

API access requires the GearDex Studio plan and a scoped Studio API key.

Scopes keep every GearDex integration narrow, understandable, and easy to revoke without affecting the rest of your workflow.

## Scope model

A key can include multiple scopes. Every endpoint declares the scope it requires, and GearDex checks that permission before accessing account data. Read access never implies write access.

Least privilege

Start with read-only scopes. Add a write scope only after the integration has a specific, reviewed operation that needs it.

## Available scopes

Nine scopes cover the six v1 resources. The routes column lists what each scope allows.

**GearDex Studio API scopes**

| Scope | Access | Grants | Routes |
| --- | --- | --- | --- |
| gear:read | read | Read inventory records and filtered gear lists. | `GET /gear` |
| gear:write | write | Create, update, and delete owned inventory records. | `POST /gearPATCH /gear/{id}DELETE /gear/{id}` |
| shoots:read | read | Read shoot plans, dates, status, locations, and progress. | `GET /shootsGET /shoots/{id}/deliverablesGET /shoots/{id}/profit` |
| shoots:write | write | Create, update, and delete shoot plans. | `POST /shootsPATCH /shoots/{id}DELETE /shoots/{id}POST /shoots/{id}/deliverablesPOST /shoots/{id}/deliverables/deliver` |
| maintenance:read | read | Read service records, schedules, providers, and cost. | `GET /maintenance` |
| maintenance:write | write | Create, update, and delete service records for owned gear. | `POST /maintenancePATCH /maintenance/{id}DELETE /maintenance/{id}` |
| documents:read | read | Read document metadata and warranty timelines. | `GET /documents` |
| analytics:read | read | Read portfolio-level inventory and operations summaries. | `GET /analytics` |
| profile:read | read | Read account and Studio profile metadata. | `GET /profile` |
| loans:read | read | Read loans with their items, gear flags, and availability for dates. | `GET /loansGET /loans/{id}GET /flagsGET /availability` |
| loans:write | write | Check gear out and in, extend or cancel loans, and flag gear. | `POST /loansPATCH /loans/{id}POST /loans/{id}/check-inPOST /flags` |
| bookings:read | read | Read bookings and inquiries from the Site. | `GET /bookingsGET /inquiries` |
| bookings:write | write | Approve or decline booking requests. | `PATCH /bookings/{id}` |
| money:read | read | Read quotes, invoices, installments, and payments. | `GET /quotesGET /invoices` |
| money:write | write | Create and send quotes, and record invoice payments. | `POST /quotesPOST /quotes/{id}/sendPOST /invoices/{id}/payments` |

## Recommended scope sets

**Recommended GearDex scope combinations**

| Integration | Scopes | Use it to |
| --- | --- | --- |
| `Inventory reporter` | `gear:read + analytics:read` | Summarize inventory composition and portfolio totals without making changes. |
| `Production briefing` | `shoots:read + gear:read + maintenance:read` | Assess upcoming work, available equipment, and service conflicts. |
| `Warranty monitor` | `documents:read + gear:read` | Associate coverage timelines with the affected equipment. |
| `Service queue sync` | `maintenance:read + maintenance:write + gear:read` | Create and update repair records while validating owned gear references. |
| `Lending desk` | `loans:read + loans:write + gear:read` | Check gear out and in from a kiosk, Slack bot, or rental tool, and chase overdue returns. |
| `Shoot planning automation` | `shoots:read + shoots:write + gear:read` | Draft and maintain production plans using live inventory context. |

## Missing scope errors

A valid key that lacks the endpoint's required permission receives a `403` response. Create or update a purpose-specific key instead of broadening unrelated integrations.

**403 response**

```json
{
  "error": "Missing required scope: maintenance:write",
  "code": "insufficient_scope"
}
```

See [Responses and errors](https://www.geardex.app/api-docs/errors) for every authentication code.

---

# Endpoints

Source: https://www.geardex.app/api-docs/endpoints

API access requires the GearDex Studio plan and a scoped Studio API key.

The v1 API maps directly to the resources photographers and production teams manage inside GearDex.

## Endpoint index

Base URL

`https://www.geardex.app/api/studio-agent/v1`

`GET` `/gear` List inventory with type, search, and pagination filters. `gear:read`

`POST` `/gear` Create an owned gear record. `gear:write`

`PATCH` `/gear/{id}` Update an owned gear record. `gear:write`

`DELETE` `/gear/{id}` Delete gear and clean related records. `gear:write`

`GET` `/shoots` List shoots with status, date, and search filters. `shoots:read`

`POST` `/shoots` Create a planning-state shoot. `shoots:write`

`PATCH` `/shoots/{id}` Update production details, status, or progress. `shoots:write`

`DELETE` `/shoots/{id}` Delete a shoot plan. `shoots:write`

`GET` `/maintenance` List service records and schedules. `maintenance:read`

`POST` `/maintenance` Create service work for owned gear. `maintenance:write`

`PATCH` `/maintenance/{id}` Update service status, cost, or provider. `maintenance:write`

`DELETE` `/maintenance/{id}` Delete a maintenance record. `maintenance:write`

`GET` `/documents` List document and warranty metadata. `documents:read`

`GET` `/analytics` Return aggregate Studio metrics. `analytics:read`

`GET` `/profile` Return account and Studio profile metadata. `profile:read`

`GET` `/loans` List loans with their items, by status, borrower, or gear. `loans:read`

`POST` `/loans` Check owned gear out to a borrower; Studio API keys support multi-item carts. `loans:write`

`GET` `/loans/{id}` Return a loan with its items and consumables. `loans:read`

`PATCH` `/loans/{id}` Extend the due date or cancel a loan. `loans:write`

`POST` `/loans/{id}/check-in` Check some or all items back in; missing items raise flags. `loans:write`

`GET` `/flags` List issues flagged on gear. `loans:read`

`POST` `/flags` Flag an issue; blocking flags take the gear out of rotation. `loans:write`

`GET` `/availability` Check whether an item can go out for a date range. `loans:read`

`GET` `/bookings` List bookings by status and start-time range. `bookings:read`

`PATCH` `/bookings/{id}` Approve or decline a booking request. `bookings:write`

`GET` `/inquiries` List leads from the Site's inquiry form. `bookings:read`

`GET` `/quotes` List quotes with status filters. Studio plan. `money:read`

`POST` `/quotes` Create a draft quote. Studio plan. `money:write`

`POST` `/quotes/{id}/send` Email the client a link to accept the quote. `money:write`

`GET` `/invoices` List invoices with installments and payments. Studio plan. `money:read`

`POST` `/invoices/{id}/payments` Record a payment against an invoice. `money:write`

`GET` `/shoots/{id}/deliverables` List a shoot's deliverables. Studio plan. `shoots:read`

`POST` `/shoots/{id}/deliverables` Add a deliverable to a shoot. `shoots:write`

`POST` `/shoots/{id}/deliverables/deliver` Mark deliverables delivered and optionally email the client. `shoots:write`

`GET` `/shoots/{id}/profit` Return a shoot's booked, collected, expenses, gear wear, and profit. `shoots:read`

Every route requires a bearer key with the listed [scope](https://www.geardex.app/api-docs/scopes). Write routes emit matching [webhook events](https://www.geardex.app/api-docs/webhooks).

## Gear

Query cameras, lenses, accessories, filters, and drones through one inventory resource. Write requests validate fields against the selected gear type and emit matching webhook events.

`GET` `/gear` List inventory with type, search, and pagination filters. `gear:read`

`POST` `/gear` Create an owned gear record. `gear:write`

`PATCH` `/gear/{id}` Update an owned gear record. `gear:write`

`DELETE` `/gear/{id}` Delete gear and clean related records. `gear:write`

### Query parameters

**GET /gear query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `type` | `enum` | all · camera · lens · accessory · filter · drone |
| `q` | `string` | Search text, up to 100 characters. |
| `limit` | `integer` | 1–100 records per page. |
| `offset` | `integer` | 0 or greater. |

### Request body

**Gear write fields**

| Field | Rule | Values |
| --- | --- | --- |
| `gear_type` | `required` | camera · lens · accessory · filter · drone. Also required on PATCH and as a query parameter on DELETE. |
| `brand / model` | `required` | Strings, up to 255 characters each. |
| `condition` | `optional` | excellent · very-good · good · fair · poor |
| `status` | `optional` | available · on-loan · maintenance · retired |
| `serial_number, purchase_date, purchase_price, notes` | `optional` | Ownership details. Type-specific fields such as mount\_type, focal\_length, and filter\_type are validated against gear\_type. |
| `updates` | `PATCH only` | Object with at least one field. Optional text, date, and number fields can be set to null to clear them. |
| `shutter_count, shutter_count_read_on, rated_shutter_life` | `read only` | Returned on cameras: the latest logged shutter count, its date, and the owner's rated life. Log readings in the app. |

**List Fujifilm gear (cURL)**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/gear?q=Fujifilm&limit=10" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

**Create a camera (cURL)**

```bash
curl -X POST "https://www.geardex.app/api/studio-agent/v1/gear" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "gear_type": "camera",
    "brand": "Fujifilm",
    "model": "X-T5",
    "condition": "excellent",
    "status": "available"
  }'
```

**Update a camera (cURL)**

```bash
curl -X PATCH "https://www.geardex.app/api/studio-agent/v1/gear/gear_item_uuid" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "gear_type": "camera",
    "updates": {
      "status": "maintenance",
      "notes": "Scheduled for sensor cleaning"
    }
  }'
```

## Shoots

Build schedule views with status and date filters, or let a trusted planning service draft and maintain shoots.

`GET` `/shoots` List shoots with status, date, and search filters. `shoots:read`

`POST` `/shoots` Create a planning-state shoot. `shoots:write`

`PATCH` `/shoots/{id}` Update production details, status, or progress. `shoots:write`

`DELETE` `/shoots/{id}` Delete a shoot plan. `shoots:write`

`GET` `/shoots/{id}/deliverables` List a shoot's deliverables. Studio plan. `shoots:read`

`POST` `/shoots/{id}/deliverables` Add a deliverable to a shoot. `shoots:write`

`POST` `/shoots/{id}/deliverables/deliver` Mark deliverables delivered and optionally email the client. `shoots:write`

`GET` `/shoots/{id}/profit` Return a shoot's booked, collected, expenses, gear wear, and profit. `shoots:read`

### Query parameters

**GET /shoots query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `status` | `enum` | planning · confirmed · completed · cancelled |
| `fromDate / toDate` | `date` | Date window, formatted YYYY-MM-DD. |
| `q` | `string` | Search text, up to 100 characters. |
| `limit / offset` | `integer` | Pagination. Limit is 1–100. |

### Request body

**Shoot write fields**

| Field | Rule | Values |
| --- | --- | --- |
| `title / client_name` | `required` | Strings, up to 160 characters each. |
| `shoot_date` | `required` | Date, formatted YYYY-MM-DD. |
| `shoot_time / shoot_end_time` | `optional` | 24-hour time, HH:MM. |
| `location / locations` | `optional` | One location, or up to 20 as an array (or a semicolon- or newline-separated string). |
| `updates` | `PATCH only` | Also accepts status (planning · confirmed · completed · cancelled) and completion\_progress (0–100). |

**Deliverable fields (Studio plan)**

| Field | Rule | Values |
| --- | --- | --- |
| `title` | `required` | POST /shoots/{id}/deliverables. Optional kind, url, and due\_date (YYYY-MM-DD). |
| `ids` | `required` | POST /shoots/{id}/deliverables/deliver: the deliverables to mark delivered. |
| `notify` | `optional` | true emails the client that their delivery is ready. |

**Upcoming confirmed shoots (cURL)**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/shoots?status=confirmed&fromDate=2026-08-01&toDate=2026-08-31&limit=10" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

**Create a shoot (cURL)**

```bash
curl -X POST "https://www.geardex.app/api/studio-agent/v1/shoots" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Coastal Editorial",
    "client_name": "Northline Apparel",
    "shoot_date": "2026-08-18",
    "shoot_time": "06:30",
    "location": "Malibu, CA"
  }'
```

## Maintenance

Service records stay connected to the exact owned item they affect. GearDex validates the gear reference before accepting a write.

`GET` `/maintenance` List service records and schedules. `maintenance:read`

`POST` `/maintenance` Create service work for owned gear. `maintenance:write`

`PATCH` `/maintenance/{id}` Update service status, cost, or provider. `maintenance:write`

`DELETE` `/maintenance/{id}` Delete a maintenance record. `maintenance:write`

### Query parameters

**GET /maintenance query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `status` | `enum` | scheduled · in\_progress · completed · cancelled |
| `fromDate / toDate` | `date` | Date window, formatted YYYY-MM-DD. |
| `q` | `string` | Search text, up to 100 characters. |
| `limit / offset` | `integer` | Pagination. Limit is 1–100. |

### Request body

**Maintenance write fields**

| Field | Rule | Values |
| --- | --- | --- |
| `item_type / item_id` | `required` | The owned gear item being serviced. item\_id is validated against item\_type. |
| `service_type` | `required` | String, up to 160 characters. |
| `service_date` | `required` | Date, formatted YYYY-MM-DD. |
| `status` | `optional` | scheduled (default) · in\_progress · completed · cancelled |
| `cost, service_provider, notes` | `optional` | Service details. Nullable on update. |

**Schedule service (cURL)**

```bash
curl -X POST "https://www.geardex.app/api/studio-agent/v1/maintenance" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "item_type": "camera",
    "item_id": "gear_item_uuid",
    "service_type": "Sensor cleaning",
    "service_date": "2026-08-21",
    "service_provider": "Local camera shop",
    "status": "scheduled"
  }'
```

## Lending

Check gear out and back in, extend loans, and flag issues. One loan can hold a whole cart of items and kits, with no limit on open loans. Check-outs emit `loan.checked_out`, completed returns `loan.returned`, and flags `flag.raised`.

`GET` `/loans` List loans with their items, by status, borrower, or gear. `loans:read`

`POST` `/loans` Check owned gear out to a borrower; Studio API keys support multi-item carts. `loans:write`

`GET` `/loans/{id}` Return a loan with its items and consumables. `loans:read`

`PATCH` `/loans/{id}` Extend the due date or cancel a loan. `loans:write`

`POST` `/loans/{id}/check-in` Check some or all items back in; missing items raise flags. `loans:write`

`GET` `/flags` List issues flagged on gear. `loans:read`

`POST` `/flags` Flag an issue; blocking flags take the gear out of rotation. `loans:write`

`GET` `/availability` Check whether an item can go out for a date range. `loans:read`

### Query parameters

**GET /loans query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `status` | `enum` | open (default) · returned · cancelled · all |
| `borrower` | `string` | Matches part of the borrower's name. |
| `gear_type / gear_id` | `enum / UUID` | Loans that included this item. |
| `limit / offset` | `integer` | Pagination. Limit is 1–100. |

**GET /flags query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `status` | `enum` | open (default) · resolved · all |
| `gear_type / gear_id` | `enum / UUID` | Flags on one item. Pass both. |

**GET /availability query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `gear_type / gear_id` | `required` | camera · lens · accessory · filter · drone, and the item's UUID. |
| `start / end` | `date` | YYYY-MM-DD. Defaults to today. |

### Request body

**POST /loans and PATCH /loans/{id} fields**

| Field | Rule | Values |
| --- | --- | --- |
| `items or kit_ids` | `required` | items: \[{ gear\_type, gear\_id }\]; kit\_ids: kit UUIDs. One loan can hold several items and kits. |
| `borrower` | `required` | { name, email, phone, client\_id }. Only name is required. |
| `due_date` | `optional` | YYYY-MM-DD. Defaults to your loan length in gear settings. |
| `loan_date, due_time, loan_type` | `optional` | loan\_date defaults to today; loan\_type is outgoing (default) or incoming. |
| `deposit_amount, purpose, notes, consumables` | `optional` | consumables: \[{ id, quantity }\], taken from stock. |
| `action` | `PATCH only` | extend (with due\_date, optional due\_time) · cancel |

**POST /loans/{id}/check-in fields**

| Field | Rule | Values |
| --- | --- | --- |
| `items` | `optional` | \[{ id, outcome, note }\] with loan item ids; outcome is returned (default) or missing. Omit to return everything still out. |
| `notes, return_date` | `optional` | return\_date is YYYY-MM-DD and defaults to today. |

**POST /flags fields**

| Field | Rule | Values |
| --- | --- | --- |
| `gear_type / gear_id` | `required` | The owned item with the issue. |
| `type` | `required` | needs\_repair · damaged · missing · dirty · sensor\_dust · low\_battery · other |
| `note` | `required` | What's wrong, up to 2,000 characters. |
| `blocks` | `optional` | true takes the item out of rotation. Defaults by type. |
| `loan_id` | `optional` | The loan the issue came back from. |

**Check a camera out (cURL)**

```bash
curl -X POST "https://www.geardex.app/api/studio-agent/v1/loans" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [{ "gear_type": "camera", "gear_id": "gear_item_uuid" }],
    "borrower": { "name": "Sam Rivera", "email": "sam@example.com" },
    "due_date": "2026-11-14"
  }'
```

**Check everything back in (cURL)**

```bash
curl -X POST "https://www.geardex.app/api/studio-agent/v1/loans/LOAN_ID/check-in" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
```

## Bookings

Read bookings and inquiries from your Site, and approve or decline booking requests.

`GET` `/bookings` List bookings by status and start-time range. `bookings:read`

`PATCH` `/bookings/{id}` Approve or decline a booking request. `bookings:write`

`GET` `/inquiries` List leads from the Site's inquiry form. `bookings:read`

### Query parameters

**GET /bookings query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `status` | `enum` | requested · confirmed · cancelled · expired |
| `from / to` | `date-time` | Start-time window, as an ISO date or date-time. |
| `limit / offset` | `integer` | Pagination. Limit is 1–100. |

**GET /inquiries query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `status` | `enum` | new · replied · converted · archived |
| `limit / offset` | `integer` | Pagination. Limit is 1–100. |

### Request body

**PATCH /bookings/{id} fields**

| Field | Rule | Values |
| --- | --- | --- |
| `action` | `required` | approve · decline, for a booking with status requested. |

**Approve a booking request (cURL)**

```bash
curl -X PATCH "https://www.geardex.app/api/studio-agent/v1/bookings/BOOKING_ID" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "action": "approve" }'
```

## Money

Quotes and invoices need the Studio plan. Create a draft quote, send it, and record payments as clients pay.

`GET` `/quotes` List quotes with status filters. Studio plan. `money:read`

`POST` `/quotes` Create a draft quote. Studio plan. `money:write`

`POST` `/quotes/{id}/send` Email the client a link to accept the quote. `money:write`

`GET` `/invoices` List invoices with installments and payments. Studio plan. `money:read`

`POST` `/invoices/{id}/payments` Record a payment against an invoice. `money:write`

### Query parameters

**GET /quotes query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `status` | `enum` | draft · sent · accepted · declined · expired |
| `limit / offset` | `integer` | Pagination. Limit is 1–100. |

**GET /invoices query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `status` | `enum` | draft · sent · paid · overdue · void |
| `limit / offset` | `integer` | Pagination. Limit is 1–100. |

### Request body

**POST /quotes fields**

| Field | Rule | Values |
| --- | --- | --- |
| `client_id or client_name` | `required` | A client from your list, or a name (with client\_email) for someone new. |
| `title` | `required` | Up to 160 characters. |
| `line_items` | `required` | 1–100 items, each { description, quantity, unit\_price, discount }. |
| `tax_rate` | `optional` | Percent, 0–100. |
| `valid_until` | `optional` | Expiry date, formatted YYYY-MM-DD. |
| `shoot_id, notes` | `optional` | Link a shoot, and add notes for the client. |

**POST /invoices/{id}/payments fields**

| Field | Rule | Values |
| --- | --- | --- |
| `amount` | `required` | Greater than 0, in the invoice's currency. The invoice must already be sent. |
| `method, paid_on, reference, notes` | `optional` | paid\_on is YYYY-MM-DD and defaults to today. |

**Create a draft quote (cURL)**

```bash
curl -X POST "https://www.geardex.app/api/studio-agent/v1/quotes" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "CLIENT_ID",
    "title": "Spring family session",
    "line_items": [{ "description": "Family session, 1 hour", "quantity": 1, "unit_price": 450 }]
  }'
```

## Read-only resources

`GET` `/documents` List document and warranty metadata. `documents:read`

`GET` `/analytics` Return aggregate Studio metrics. `analytics:read`

`GET` `/profile` Return account and Studio profile metadata. `profile:read`

### Document filters

**GET /documents query parameters**

| Parameter | Type | Values |
| --- | --- | --- |
| `documentType` | `enum` | receipt · warranty · insurance · user\_manual |
| `gearItemType` | `enum` | camera · lens · accessory · filter · drone |
| `warrantyStatus` | `enum` | expired · critical · urgent · warning · active |
| `fromDate / toDate` | `date` | Date window, formatted YYYY-MM-DD. |
| `q` | `string` | Search text, up to 100 characters. |
| `limit / offset` | `integer` | Pagination. Limit is 1–100. |

**Analytics summary (cURL)**

```bash
curl -X GET "https://www.geardex.app/api/studio-agent/v1/analytics" \
  -H "Authorization: Bearer gdx_live_your_key_here" \
  -H "Accept: application/json"
```

Sample analytics and profile payloads are on [What can you build?](https://www.geardex.app/api-docs/what-can-you-build#additional-endpoints)

## Pagination

Collection endpoints use `limit` and `offset`. Responses include returned and total counts so clients can advance through results without guessing.

**Pagination shape**

```json
{
  "pagination": {
    "limit": 25,
    "offset": 0,
    "returned": 25,
    "total": 83
  }
}
```

---

# Responses and errors

Source: https://www.geardex.app/api-docs/errors

API access requires the GearDex Studio plan and a scoped Studio API key.

Keep the HTTP status, machine-readable code, and request context together so a failed call is easy to diagnose.

## Response shape

Successful list requests return a `data` array plus pagination fields. Failed requests return an `error` message and a stable `code` that your integration can branch on. The message includes the detail an operator needs to act.

**Error response**

```json
{
  "error": "Missing required scope: shoots:write",
  "code": "insufficient_scope"
}
```

Branch on the code

Messages may become clearer over time. Treat  `code`  as the programmatic value and show  `error`  to the operator.

## Status codes

**GearDex Studio API response status codes**

| Status | Meaning | When |
| --- | --- | --- |
| `200 / 201` | Success | The request completed. Create operations return the new record. |
| `400` | Bad request | A parameter or request body failed validation. |
| `401` | Unauthorized | The bearer token is missing, malformed, unknown, revoked, or expired. |
| `403` | Forbidden | The key lacks a required scope or the account cannot use the Studio API. |
| `404` | Not found | The requested record does not exist in the authenticated account. |
| `409` | Conflict | The write conflicts with the current record or a related resource. |
| `429` | Rate limited | The key exhausted its current one-minute request window. |
| `503` | Unavailable | GearDex could not safely check the rate limit or complete a dependent operation. |
| `500` | Server error | An unexpected server error prevented the request from completing. |

## Authentication codes

**GearDex Studio API authentication error codes**

| Code | Status | Meaning |
| --- | --- | --- |
| `missing_authorization` | `401` | The Authorization header was not sent. |
| `invalid_token` | `401` | The bearer value is malformed or is not a GearDex Studio key. |
| `key_not_found` | `401` | No active key matches the supplied token. |
| `key_revoked` | `401` | The key was revoked in GearDex settings. |
| `key_expired` | `401` | The key is past its configured expiration date. |
| `insufficient_scope` | `403` | The route requires a scope that the key does not have. |
| `feature_not_available` | `403` | Studio API access is not available for the account. |
| `rate_limited` | `429` | The key reached its request limit for the current window. |
| `rate_limit_unavailable` | `503` | GearDex could not verify the request window safely. |
| `studio_agent_config_error` | `503` | The server-side Studio API configuration is incomplete. |

## Validation errors

Query values and JSON bodies are checked before a route touches your workspace. List limits cannot exceed 100, offsets cannot be negative, and search text is capped at 100 characters. Write routes also check resource-specific fields and ownership.

**Handle a failed request (JavaScript)**

```js
const response = await fetch(url, options)
const body = await response.json()

if (!response.ok) {
  throw new Error("GearDex request failed: " + (body.code ?? response.status))
}

return body
```

## Retry safely

Retry read requests after short network failures and selected 5xx responses. For a 429, wait for the number of seconds in `Retry-After`, add a small random delay, and try again. The [rate limits](https://www.geardex.app/api-docs/rate-limits) page has a backoff example.

Be careful with writes

Do not replay a create, update, or delete request blindly. First check whether the original write completed, especially after a timeout where the client never received the response.

---

# Rate limits

Source: https://www.geardex.app/api-docs/rate-limits

API access requires the GearDex Studio plan and a scoped Studio API key.

Smooth out bursts, respect the retry signal, and keep background jobs from competing for the same key.

## Limit model

120

requests per key

60 s

fixed window

429

when exhausted

The current default is **120 requests per minute for each API key**. GearDex counts requests in a fixed 60-second window. Two services using the same key also share the same window.

Defaults can differ

GearDex can set a different limit for an environment. Treat 120 per minute as the current default, not a permanent contract.

**GearDex Studio API rate limit model**

| Part | Value | Detail |
| --- | --- | --- |
| `Key` | `gdx_live_*` | The request count is isolated by Studio API key. |
| `Window` | `60 seconds` | A fixed window begins when the counter is created. |
| `Default limit` | `120` | The current default maximum requests in one window. |
| `Configuration` | `Server setting` | STUDIO\_AGENT\_KEY\_RATE\_LIMIT\_PER\_MINUTE can override the per-key cap. |
| `Storage` | `Distributed` | Supabase counters enforce the same key limit across replicas. If unavailable, access fails closed with 503. |

## Throttled response

When a key reaches its current window, GearDex responds with `429 Too Many Requests`. The `Retry-After` header gives the minimum whole number of seconds to wait.

**429 response**

```http
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 18

{
  "error": "API key rate limit exceeded",
  "code": "rate_limited"
}
```

## Backoff

Honor `Retry-After` first. Add jitter so several workers do not wake at the same instant, then cap the number of attempts. Keep the original request context in logs so a delayed failure can be traced.

**Wait before retrying (JavaScript)**

```js
const retryAfter = Number(response.headers.get("retry-after") ?? 1)
const jitter = Math.floor(Math.random() * 500)

await new Promise((resolve) =>
  setTimeout(resolve, retryAfter * 1000 + jitter),
)

// Retry only when the operation is safe to send again.
```

## Traffic design

- Use separate keys for separate services so one burst does not stall every integration.
- Fetch list endpoints in pages of up to 100 instead of one record at a time.
- Cache stable profile and document metadata where it is safe to do so.
- Use [webhooks](https://www.geardex.app/api-docs/webhooks) for change notifications instead of frequent polling.
- Queue background work and set a concurrency limit per key.

## Service availability

GearDex returns `503 rate_limit_unavailable` when it cannot safely read or update the counter. This differs from a 429: the key did not necessarily exhaust its window, and the service cannot confirm its current count.

Fail closed

Pause the job and retry later with backoff. Do not treat a 503 from the limiter as permission to send the request without a count.

---

# Webhooks

Source: https://www.geardex.app/api-docs/webhooks

API access requires the GearDex Studio plan and a scoped Studio API key.

Keep external systems synchronized with signed events emitted by Studio API writes and matching changes inside GearDex.

## Event delivery

GearDex sends an HTTP `POST` request to each subscribed endpoint. The body is JSON and the signature covers the exact raw body bytes received by your server.

Acknowledge quickly

Verify the signature, persist the event ID, and return a successful response before starting slow downstream work.

**Webhook delivery behavior**

| Rule | Value | Detail |
| --- | --- | --- |
| `Method` | POST | JSON body, User-Agent GearDex-Webhooks/1.0. |
| `Timeout` | 5 seconds | A delivery that does not respond in time counts as failed. |
| `Success` | 2xx | Any other status is recorded as a failed attempt. |
| `Attempts` | Up to 5 | Retries after 15 minutes, 1 hour, 6 hours, then 24 hours. |
| `Endpoint URL` | HTTPS | Private, local, and credential-bearing URLs are rejected. |

## Events

Subscribe each endpoint to the events it needs. Studio API writes and matching changes inside GearDex both emit events.

Gear

`gear.created` `gear.updated` `gear.deleted`

Shoots

`shoot.created` `shoot.updated` `shoot.deleted`

Maintenance

`maintenance.created` `maintenance.updated` `maintenance.deleted`

Lending

`loan.checked_out` `loan.returned` `loan.due_soon` `loan.overdue` `flag.raised`

API keys

`api_key.created` `api_key.revoked`

Testing

`webhook.test`

Business

`booking.requested` `booking.confirmed` `booking.cancelled` `quote.accepted` `contract.signed` `invoice.paid` `deliverable.delivered`

## Payload

Every delivery wraps the changed record in the same envelope. `data` carries the record fields, for example `gear_type` and `id` on gear events.

**Event body**

```json
{
  "id": "event_uuid",
  "type": "gear.updated",
  "created_at": "2026-08-02T19:48:22.000Z",
  "data": { }
}
```

## Headers

**GearDex webhook request headers**

| Header | Format | Description |
| --- | --- | --- |
| `X-GearDex-Event-Id` | `UUID` | Stable identifier for idempotency and replay protection. |
| `X-GearDex-Event-Type` | `string` | Event name such as gear.updated, shoot.created, or webhook.test. |
| `X-GearDex-Webhook-Id` | `UUID` | The configured Studio webhook endpoint that received the event. |
| `X-GearDex-Timestamp` | `Unix time` | Timestamp included in the signed payload string. |
| `X-GearDex-Signature` | `HMAC-SHA256` | Signature formatted as t=<timestamp>,v1=<hex digest>. |

## Verify signatures

Compute the expected digest from `<timestamp>.<rawBody>` and the endpoint's signing secret. Compare signatures with a constant-time function.

**Verify signature (Node.js)**

```js
import crypto from "node:crypto"

export function verifyGearDexWebhook({ rawBody, signatureHeader, signingSecret }) {
  const parts = Object.fromEntries(
    signatureHeader.split(",").map((part) => part.split("="))
  )
  const timestamp = parts.t
  const signature = parts.v1
  if (!timestamp || !signature) return false

  const expected = crypto
    .createHmac("sha256", signingSecret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex")

  if (signature.length !== expected.length) return false

  return crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex")
  )
}
```

Prevent replay

Reject stale timestamps and store processed event IDs. Signature verification alone does not prevent a valid delivery from being replayed.

## Receive an event

**Next.js route handler**

```ts
import { NextResponse } from "next/server"
import { verifyGearDexWebhook } from "@/site/lib/geardex-webhooks"

export async function POST(request) {
  const rawBody = await request.text()
  const verified = verifyGearDexWebhook({
    rawBody,
    signatureHeader: request.headers.get("x-geardex-signature") || "",
    signingSecret: process.env.GEARDEX_WEBHOOK_SECRET,
  })

  if (!verified) {
    return NextResponse.json({ error: "Invalid signature" }, { status: 401 })
  }

  const event = JSON.parse(rawBody)
  // Enqueue work using event.id as the idempotency key.
  return NextResponse.json({ received: event.id })
}
```

## Retries and replay

GearDex retries failed deliveries on a backoff schedule. Studio owners can inspect and replay recent deliveries from Settings, so consumers should treat the event ID as an idempotency key.

- Return a 2xx response only after the event is safely accepted.
- Expect the same event ID to arrive more than once.
- Keep signing secrets outside source control.
- Rotate an endpoint secret after suspected exposure.

## Endpoint templates

GearDex offers starting templates when you add an endpoint in Settings. Each one preselects the recommended events.

Automation Intake

Zapier / Make

Send new and changed shoot work into no-code automation flows.

`shoot.created``shoot.updated``gear.updated`

CRM Handoff

Client Ops

Notify a CRM or client workspace when shoots move forward.

`shoot.created``shoot.updated``shoot.deleted`

Inventory Sync

Asset Systems

Mirror gear additions, edits, and removals into external asset tools.

`gear.created``gear.updated``gear.deleted`

Maintenance Alerts

Ops Queue

Push service records into shop queues, Slack-style alerts, or work orders.

`maintenance.created``maintenance.updated``maintenance.deleted`

Lending Alerts

Slack / Ops

Post check-outs, returns, overdue gear, and flagged issues to a team channel.

`loan.checked_out``loan.returned``loan.due_soon``loan.overdue``flag.raised`

Security Audit

Access Review

Track Studio API key creation and revocation in an external audit log.

`api_key.created``api_key.revoked`

Need the raw change feed instead?

 [Browse the endpoint reference](https://www.geardex.app/api-docs/endpoints)

---

# OpenAPI specification

Source: https://www.geardex.app/api-docs/openapi

API access requires the GearDex Studio plan and a scoped Studio API key.

Use the live GearDex contract with API clients, collection importers, schema validators, and code generators.

## Live specification

GearDex serves its v1 Studio contract as OpenAPI JSON. The document is public so tooling can read endpoint schemas before you provide a key for authenticated requests.

`GET` `/api/studio-agent/openapi` OpenAPI 3.1 · GearDex Studio Agent API 1.0.0

[Open the live OpenAPI JSON](https://www.geardex.app/api/studio-agent/openapi)

Canonical source

Point automated tooling at the live URL instead of committing a stale copy unless your release process intentionally pins API contracts.

## Download

**Download OpenAPI JSON**

```bash
curl -L "https://www.geardex.app/api/studio-agent/openapi" \
  -H "Accept: application/json" \
  -o geardex-openapi.json
```

The endpoint does not require a Studio API key. Generated clients must still send a scoped bearer key when they call protected v1 resources.

## Client generation

Most OpenAPI-compatible generators can consume the live URL directly. Keep generated clients behind a server boundary so credentials never enter browser code.

**Generate TypeScript types**

```bash
npx openapi-typescript "https://www.geardex.app/api/studio-agent/openapi" \
  --output src/generated/geardex-api.d.ts
```

1. Generate types or a client during development or CI.
2. Review contract changes before updating application code.
3. Inject the Studio key at server runtime.
4. Preserve response status and error bodies for debugging.

## Coverage

**OpenAPI resource coverage**

| Resource | Shape | Operations |
| --- | --- | --- |
| `Gear` | `collection + detail` | List, create, update, and delete inventory records. |
| `Shoots` | `collection + detail` | List, create, update, and delete shoot plans. |
| `Maintenance` | `collection + detail` | List, create, update, and delete service records. |
| `Documents` | `collection` | Read document and warranty metadata. |
| `Analytics` | `summary` | Read aggregate Studio metrics. |
| `Profile` | `resource` | Read account and Studio profile metadata. |
| `Loans` | `collection + detail` | List loans, check gear out and in, extend, and cancel. |
| `Flags and availability` | `collection + query` | Read and raise gear issues; check an item's availability for dates. |

Dashboard-only operations

API key management, activity logs, and webhook endpoint configuration use authenticated GearDex dashboard sessions and are not part of the Studio bearer API specification.

---

# Audit activity

Source: https://www.geardex.app/api-docs/audit-logs

API access requires the GearDex Studio plan and a scoped Studio API key.

See which key touched which route, how GearDex answered, and where a failed request came from.

## What is recorded

GearDex writes an audit entry for Studio API requests and key management actions. Request entries pair the route and method with the key, required scope, HTTP result, and authentication result.

**GearDex API audit entry fields**

| Field | Type | Description |
| --- | --- | --- |
| `event_type` | `string` | The action, such as api\_request, key\_create, key\_revoke, or key\_list. |
| `api_key_id / api_key` | `string / object` | The key ID plus its display name and safe prefix, when a key applies. |
| `route / method` | `string` | The requested API route and HTTP method. |
| `scope` | `scope` | The permission checked for the request. |
| `status_code` | `number` | The HTTP result returned to the caller. |
| `auth_code` | `string` | The authentication outcome or error code. |
| `ip_address` | `string` | The source IP address recorded for the request. |
| `user_agent` | `string` | The client user-agent value, when supplied. |
| `metadata` | `JSON` | Extra request context, including request IDs where available. |
| `created_at` | `timestamp` | When GearDex recorded the event. |

## Event types

**GearDex API audit event types**

| Event | Kind | Recorded when |
| --- | --- | --- |
| `api_request` | Request | A Studio API route received a request. |
| `key_create` | Key management | A workspace member created a new Studio key. |
| `key_revoke` | Key management | A workspace member revoked a Studio key. |
| `key_list` | Key management | A workspace member opened the API key list. |

## Read activity

Audit activity belongs to the signed-in GearDex workspace. It is not a bearer-key route in the public Studio API. [Sign in](https://www.geardex.app/signin), open **Settings**, and choose **API & Agents** to inspect activity through the authenticated dashboard.

Dashboard authentication

The internal activity request defaults to 25 entries and accepts up to 100 per page. It uses the signed-in GearDex session, not a  `gdx_live_`  key.

**Audit activity response shape**

```json
{
  "logs": [
    {
      "event_type": "api_request",
      "method": "GET",
      "route": "/api/studio-agent/v1/gear",
      "scope": "gear:read",
      "status_code": 200,
      "created_at": "2026-08-02T19:48:22.000Z"
    }
  ],
  "pagination": {
    "limit": 25,
    "returned": 1
  }
}
```

## Investigation workflow

1. Start with the time, route, method, and status code reported by the integration.
2. Match the key name and request ID to the corresponding audit entry.
3. Check the required [scope](https://www.geardex.app/api-docs/scopes) and [authentication code](https://www.geardex.app/api-docs/errors#authentication-codes) before changing permissions.
4. Compare the source IP and user agent with the expected service.
5. Revoke the key if its origin or request pattern is unfamiliar.

## Privacy and retention

Audit entries can contain IP addresses, user-agent strings, route names, and request metadata. Limit access to workspace members who need operational or security visibility, and avoid placing secrets or sensitive client data in query strings.

Keys are never logged

GearDex records the key identity and display name, not the raw API secret. The complete secret is shown only once when the key is created.

---

# MCP adapter

Source: https://www.geardex.app/api-docs/mcp-adapter

API access requires the GearDex Studio plan and a scoped Studio API key.

Use GearDex MCP tools on top of the Studio API for agent-friendly workflows.

## Overview

The MCP adapter wraps the Studio API and exposes tool-style methods for agent runtimes like Claude Desktop, Cursor, and custom MCP hosts.

Use MCP when you want an AI agent to call controlled Studio tools instead of crafting raw HTTP requests.

## Getting started

Install Node 22 or newer, then use the standalone adapter below. No GitHub account, npm account, source checkout or access to the GearDex repository is required. The download contains only the MCP API client and its bundled dependencies.

1. Create a Studio API key in **Settings**, **API & Agents** with only the [scopes](https://www.geardex.app/api-docs/scopes) your agent needs.
2. Install Node 22 or newer if it is not already installed.
3. Copy the MCP configuration below into your agent host and replace the API key placeholder.
4. Restart the host so it starts the downloaded adapter.
5. Run a first call like `list_gear` to verify connectivity and auth.

**Run the standalone adapter**

```bash
npx --yes --package https://github.com/dylandersen/geardex-public/releases/download/mcp-v0.1.0/geardex-mcp-0.1.0.tgz geardex-mcp
```

**Environment variables**

```env
GEARDEX_BASE_URL=https://www.geardex.app
GEARDEX_STUDIO_API_KEY=gdx_live_your_key_here
```

You can use either `https://www.geardex.app` or `https://geardex.app`. The MCP adapter handles the domain alias redirect while preserving authentication.

[Download adapter 0.1.0](https://github.com/dylandersen/geardex-public/releases/download/mcp-v0.1.0/geardex-mcp-0.1.0.tgz) or view the [release and SHA-256 checksum](https://github.com/dylandersen/geardex-public/releases/tag/mcp-v0.1.0). The first launch downloads the package; later launches use the local npm cache. Downloads are versioned, so updates are explicit.

## Configure an agent

This example works for Claude Desktop-style stdio MCP configs. On Windows, change the command from `npx`  to `npx.cmd`. Use a Node 22+ installation visible to your host.

**MCP config**

```json
{
  "mcpServers": {
    "geardex": {
      "command": "npx",
      "args": [
        "--yes",
        "--package",
        "https://github.com/dylandersen/geardex-public/releases/download/mcp-v0.1.0/geardex-mcp-0.1.0.tgz",
        "geardex-mcp"
      ],
      "env": {
        "GEARDEX_STUDIO_API_KEY": "gdx_live_REPLACE_ME"
      }
    }
  }
}
```

Use your Studio API key

Replace  `gdx_live_REPLACE_ME`  with the key you created. Read tools need read scopes; changing records needs the corresponding write scopes. Keep the key in your host configuration, and never share it with another person.

**First validation prompt**

```text
List my 5 most recent gear items and group them by type.
Then show the total count by type.
```

## Technical guide

Request flow:

1. Your agent host invokes an MCP tool (for example `list_shoots`).
2. The GearDex MCP adapter maps that tool to a Studio API endpoint.
3. The adapter sends a bearer-token request using your scoped API key.
4. The Studio API enforces scopes, user ownership, and audit logging server-side.
5. The adapter returns structured JSON back to the host as MCP tool output.

**MCP adapter behavior**

| Aspect | Kind | Behavior |
| --- | --- | --- |
| `Auth` | behavior | Bearer token from GEARDEX\_STUDIO\_API\_KEY on every request. |
| `Timeout` | behavior | One 20 second deadline per API call, including redirects and response reads. Responses are capped at 2 MiB. |
| `Redirect handling` | behavior | At most three redirects within the API path. Credentials stay on the same origin or HTTPS GearDex aliases; write redirects must preserve the HTTP method. |
| `State` | behavior | Stateless; no credential or session storage inside the MCP server. |
| `Write access` | behavior | MCP exposes gear, shoot, and maintenance create/update/delete tools, plus lending tools that check gear out and in and flag issues. Each tool uses the same Studio API write scopes, audit logging, and webhook emission as direct HTTP calls. |

Need raw endpoint schemas for custom clients? Use the [OpenAPI document](https://www.geardex.app/api/studio-agent/openapi) or read the [OpenAPI guide](https://www.geardex.app/api-docs/openapi).

## Tool map

37 tools, each gated by the same scope as the endpoint it calls.

**GearDex MCP tools**

| Tool | Scope | Maps to |
| --- | --- | --- |
| `list_gear` | `gear:read` | GET /gear with type/search/pagination filters. |
| `find_gear` | `gear:read` | Search helper over gear brand/model with required query. |
| `get_gear_totals` | `gear:read` | Aggregated count by gear type. |
| `create_gear` | `gear:write` | POST /gear for trusted inventory sync tools. |
| `update_gear` | `gear:write` | PATCH /gear/{id} for trusted inventory updates. |
| `delete_gear` | `gear:write` | DELETE /gear/{id} for trusted inventory cleanup. |
| `list_shoots` | `shoots:read` | GET /shoots with status/date/search filters. |
| `create_shoot` | `shoots:write` | POST /shoots for trusted planning automations. |
| `update_shoot` | `shoots:write` | PATCH /shoots/{id} for timing, status, location, notes, or progress updates. |
| `delete_shoot` | `shoots:write` | DELETE /shoots/{id} for cancelled or duplicate plans. |
| `list_maintenance` | `maintenance:read` | GET /maintenance with status/date/search filters. |
| `create_maintenance` | `maintenance:write` | POST /maintenance for owned gear service scheduling. |
| `update_maintenance` | `maintenance:write` | PATCH /maintenance/{id} for status, cost, provider, date, notes, or gear reference updates. |
| `delete_maintenance` | `maintenance:write` | DELETE /maintenance/{id} for trusted service-record cleanup. |
| `list_documents` | `documents:read` | GET /documents with type, warranty, date, and search filters. |
| `get_analytics_summary` | `analytics:read` | GET /analytics aggregate summary payload. |
| `get_profile` | `profile:read` | GET /profile account + studio profile metadata. |
| `list_loans` | `loans:read` | GET /loans with status, borrower, and gear filters; each loan lists its items. |
| `get_loan` | `loans:read` | GET /loans/{id} with items and consumables. |
| `check_out_gear` | `loans:write` | POST /loans: check items or a kit out to a borrower. |
| `check_in_loan` | `loans:write` | POST /loans/{id}/check-in: return everything, or chosen items. |
| `extend_loan` | `loans:write` | PATCH /loans/{id} with a new due date. |
| `list_flags` | `loans:read` | GET /flags: open or resolved issues on gear. |
| `flag_gear` | `loans:write` | POST /flags: raise an issue on an item. |
| `check_availability` | `loans:read` | GET /availability for an item and date range. |
| `list_bookings` | `bookings:read` | GET /bookings with status/time filters. |
| `decide_booking_request` | `bookings:write` | PATCH /bookings/{id}: approve or decline; emails the client. |
| `list_inquiries` | `bookings:read` | GET /inquiries with status filters. |
| `list_quotes` | `money:read` | GET /quotes with status filters. |
| `create_quote` | `money:write` | POST /quotes: create a draft with line items and tax; does not send it. |
| `send_quote` | `money:write` | POST /quotes/{id}/send: email the client an acceptance link. |
| `list_invoices` | `money:read` | GET /invoices with installments and payments. |
| `record_payment` | `money:write` | POST /invoices/{id}/payments: record a manual payment. |
| `list_deliverables` | `shoots:read` | GET /shoots/{id}/deliverables. |
| `add_deliverable` | `shoots:write` | POST /shoots/{id}/deliverables: add a deliverable. |
| `deliver_to_client` | `shoots:write` | POST /shoots/{id}/deliverables/deliver: mark delivered and optionally email. |
| `get_shoot_profit` | `shoots:read` | GET /shoots/{id}/profit: booked/collected revenue, expenses and wear. |

## Workflow ideas

High-value ways to use MCP with your Studio data:

**MCP workflow ideas**

| Workflow | Kind | Tools |
| --- | --- | --- |
| `Weekly Ops Brief` | automation | Run list\_shoots + get\_analytics\_summary and post a weekly studio digest. |
| `Pre-Shoot Gear Check` | assistant | Use list\_shoots + list\_gear + list\_maintenance before confirmed shoots. |
| `Service Queue Sync` | automation | Use create\_maintenance + update\_maintenance to mirror repair queue changes into GearDex. |
| `Warranty Risk Monitor` | automation | Use list\_documents with warranty filters and flag expiring coverage. |
| `Client Prep Snapshot` | assistant | Use find\_gear and list\_gear to produce packlists for an upcoming job. |
| `Overdue Chaser` | automation | Run list\_loans with status open each morning and post overdue borrowers to Slack. |
| `Executive KPI Card` | dashboard | Use get\_analytics\_summary daily and render KPI cards in Slack or Notion. |

**Prompt pattern: weekly studio brief**

```text
Use GearDex MCP tools to generate a Monday brief:
1) list_shoots for the next 14 days
2) list_maintenance for scheduled/in_progress items
3) list_documents where warrantyStatus is warning or critical
4) get_analytics_summary

Return:
- risks
- upcoming workload
- inventory readiness summary
```

**Prompt pattern: trusted maintenance update**

```text
Use GearDex MCP tools to close this service ticket:
1) find_gear for "Sony A7S III"
2) create_maintenance with service_type "Sensor cleaning"
3) update_maintenance to completed when the ticket is closed

Only use write tools if the configured API key includes maintenance:write.
```

## Security checklist

- Use one key per agent runtime.
- Grant minimum scopes required for that specific agent.
- Prefer expiring keys and rotate regularly.
- Revoke immediately if a host or workstation is compromised.
- Monitor [audit activity](https://www.geardex.app/api-docs/audit-logs) in Settings, under API & Agents.

## Troubleshooting

**MCP troubleshooting**

| Symptom | Area | Fix |
| --- | --- | --- |
| `Adapter will not start` | `setup` | Install Node 22+ and make npx visible to the agent host. On Windows use npx.cmd. Use the public adapter download, replace the key placeholder and restart the host. |
| `401 key_not_found` | `auth` | The key is unknown. Create a new key after pepper rotation; revoked and expired keys report key\_revoked and key\_expired separately. |
| `403 insufficient_scope` | `authz` | The tool requires a scope your key does not include. |
| `429 rate_limited` | `limits` | Back off and retry using Retry-After from the response. |
| `503 rate_limit_unavailable` | `availability` | Distributed limiter unavailable. Wait and retry reads; check state before retrying writes. |
| `Timed out` | `network` | A write may have completed. Inspect the relevant list before retrying; mutations have no idempotency-key guarantee. |
| `Invalid input` | `validation` | Use real UUIDs and calendar dates. Updates need at least one supported field. |
| `Empty datasets` | `data` | Key is valid but the account has no records for that scope or filter range. |
