API quickstart
This guide verifies your key, reads customers, and creates one ticket. You need an API-enabled Business workspace and a key with customers.read and tickets.write. Use a separate development workspace with fictional data for the write example. See Authentication to create a key.
1. Set your API key
Section titled “1. Set your API key”Store your key in an environment variable so you don’t accidentally paste it into code.
export BENCHKEY_API_KEY=YOUR_DEVELOPMENT_WORKSPACE_KEYbk_test_ is a key label, not an isolated sandbox. It can read and change the same workspace data as a live key. Confirm the tenant_id in the next step before creating anything.
2. Verify your key: GET /me
Section titled “2. Verify your key: GET /me”GET /me returns the authenticated tenant and key metadata. It’s the fastest way to confirm your key works.
curl https://app.benchkey.com/api/v1/me \ -H "Authorization: Bearer $BENCHKEY_API_KEY" \Node.js
Section titled “Node.js”const res = await fetch("https://app.benchkey.com/api/v1/me", { headers: { Authorization: `Bearer ${process.env.BENCHKEY_API_KEY}`, },});const data = await res.json();console.log(data);Response
Section titled “Response”{ "object": "api_key", "id": "ak_a1b2c3d4e5f6a1b2c3d4e5f6", "tenant_id": 42, "env": "live", "name": "My Integration", "key_hint": "ABCD", "scopes": ["customers.read", "tickets.read", "tickets.write"], "created_at": "2026-06-01T12:00:00.000Z", "last_used_at": "2026-06-13T09:15:00.000Z"}If you see 401 Unauthorized, double-check that the key is copied correctly and has not been revoked.
3. List customers: GET /customers
Section titled “3. List customers: GET /customers”Fetch the first page of customers in your shop. Requires the customers.read scope.
curl "https://app.benchkey.com/api/v1/customers?limit=5" \ -H "Authorization: Bearer $BENCHKEY_API_KEY" \Node.js
Section titled “Node.js”const res = await fetch( "https://app.benchkey.com/api/v1/customers?limit=5", { headers: { Authorization: `Bearer ${process.env.BENCHKEY_API_KEY}`, }, });const data = await res.json();console.log(data);Response
Section titled “Response”{ "object": "list", "data": [ { "object": "customer", "id": "jane@example.com", "display_name": "Jane Smith", "email": "jane@example.com", "emails": ["jane@example.com"], "phone": "+15550001234", "phones": ["+15550001234"], "created_at": "2025-05-15T09:30:00.000Z", "updated_at": "2025-05-15T09:30:00.000Z" } ], "has_more": true, "next_cursor": "eyJjcmVhdGVkX2F0IjoxNzQ3MzA2NjAwMDAwLCJpZCI6ImphbmVAZXhhbXBsZS5jb20ifQ"}Pass ?cursor=<next_cursor> on the next request to fetch the following page. See Pagination for details.
4. Create a ticket: POST /tickets
Section titled “4. Create a ticket: POST /tickets”Create a repair ticket for an existing customer. Requires the tickets.write scope.
curl -X POST https://app.benchkey.com/api/v1/tickets \ -H "Authorization: Bearer $BENCHKEY_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: my-unique-request-id-001" \ -d '{ "customer_email": "jane@example.com", "customer_name": "Jane Smith", "device_name": "iPhone 14", "service_name": "Screen replacement", "device_category": "Phone", "notes": "Cracked screen" }'Node.js
Section titled “Node.js”const res = await fetch("https://app.benchkey.com/api/v1/tickets", { method: "POST", headers: { Authorization: `Bearer ${process.env.BENCHKEY_API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": "my-unique-request-id-001", }, body: JSON.stringify({ customer_email: "jane@example.com", customer_name: "Jane Smith", device_name: "iPhone 14", service_name: "Screen replacement", device_category: "Phone", notes: "Cracked screen", }),});const ticket = await res.json();console.log(ticket);Response
Section titled “Response”{ "object": "ticket", "id": "1042", "status": "Intake", "device": "iPhone 14", "customer": { "object": "ticket_customer", "name": "Jane Smith", "email": "jane@example.com", "phone": null }, "created_at": "2025-06-13T14:22:00.000Z", "updated_at": "2025-06-13T14:22:00.000Z"}The Idempotency-Key header is required. Reuse the same key only to retry this identical submission; choose a new key for a new ticket. Confirm the returned ticket ID with GET /api/v1/tickets/:id. See Idempotency.
What’s next
Section titled “What’s next”- Errors, understand error envelopes and codes before handling them in production
- Pagination, iterate through large result sets with cursors
- Rate limits, stay within limits and implement backoff
- Idempotency, make writes safe to retry
- Webhooks, get notified when things change instead of polling