providers/claude/plugin/skills/apideck-rest/SKILL.md
Apideck Unified REST API reference for any language. Use when building integrations with accounting software (QuickBooks, Xero, NetSuite), CRMs (Salesforce, HubSpot, Pipedrive), HRIS platforms (Workday, BambooHR), file storage (Google Drive, Dropbox, Box), ATS systems (Greenhouse, Lever), e-commerce, or any of Apideck's 200+ connectors using direct HTTP calls. Covers authentication headers, CRUD operations, cursor-based pagination, filtering, sorting, error handling, rate limiting, pass-through parameters, and webhooks. Language-agnostic — works with curl, fetch, axios, httpx, or any HTTP client.
npx skillsauth add apideck-libraries/api-skills apideck-restInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The Apideck Unified API provides a single REST endpoint to connect with 200+ third-party services across accounting, CRM, HRIS, file storage, ATS, e-commerce, and more. This skill covers direct HTTP usage for any language.
Base URL: https://unify.apideck.com
Authorization, x-apideck-app-id, and x-apideck-consumer-id.x-apideck-service-id to specify which downstream connector to use. Required when a consumer has multiple connections for the same API.meta.cursors.next is null.filter query parameters to narrow results server-side. DO NOT fetch all records and filter client-side.fields query parameter to request only the columns you need.Every request requires these headers:
| Header | Required | Description |
|--------|----------|-------------|
| Authorization | Yes | Bearer {API_KEY} |
| x-apideck-app-id | Yes | Your Apideck application ID |
| x-apideck-consumer-id | Yes | End-user/customer ID stored in Vault |
| x-apideck-service-id | No | Downstream connector ID (e.g., salesforce, quickbooks) |
| Content-Type | Yes (POST/PATCH) | application/json |
All resources follow a consistent URL pattern:
GET /{api}/{resource} → List
POST /{api}/{resource} → Create
GET /{api}/{resource}/{id} → Get
PATCH /{api}/{resource}/{id} → Update
DELETE /{api}/{resource}/{id} → Delete
curl -X GET 'https://unify.apideck.com/crm/contacts?limit=20&filter[email][email protected]&sort[by]=updated_at&sort[direction]=desc&fields=id,name,email' \
-H 'Authorization: Bearer {API_KEY}' \
-H 'x-apideck-app-id: {APP_ID}' \
-H 'x-apideck-consumer-id: {CONSUMER_ID}' \
-H 'x-apideck-service-id: salesforce'
Response:
{
"status_code": 200,
"status": "OK",
"service": "salesforce",
"resource": "contacts",
"operation": "all",
"data": [
{ "id": "contact_123", "name": "John Doe", "email": "[email protected]" }
],
"meta": {
"items_on_page": 20,
"cursors": {
"previous": null,
"current": "em9oby1jcm06Om9mZnNldDo6MA==",
"next": "em9oby1jcm06Om9mZnNldDo6MjA="
}
},
"links": {
"previous": null,
"current": "https://unify.apideck.com/crm/contacts?cursor=...",
"next": "https://unify.apideck.com/crm/contacts?cursor=..."
}
}
curl -X POST 'https://unify.apideck.com/crm/contacts' \
-H 'Authorization: Bearer {API_KEY}' \
-H 'Content-Type: application/json' \
-H 'x-apideck-app-id: {APP_ID}' \
-H 'x-apideck-consumer-id: {CONSUMER_ID}' \
-H 'x-apideck-service-id: salesforce' \
-d '{
"first_name": "John",
"last_name": "Doe",
"title": "VP of Engineering",
"emails": [{"email": "[email protected]", "type": "primary"}],
"phone_numbers": [{"number": "+1234567890", "type": "mobile"}],
"addresses": [{
"type": "primary",
"street_1": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country": "US"
}]
}'
Response: 201 Created with { "data": { "id": "contact_123" } }
curl -X GET 'https://unify.apideck.com/crm/contacts/contact_123' \
-H 'Authorization: Bearer {API_KEY}' \
-H 'x-apideck-app-id: {APP_ID}' \
-H 'x-apideck-consumer-id: {CONSUMER_ID}' \
-H 'x-apideck-service-id: salesforce'
curl -X PATCH 'https://unify.apideck.com/crm/contacts/contact_123' \
-H 'Authorization: Bearer {API_KEY}' \
-H 'Content-Type: application/json' \
-H 'x-apideck-app-id: {APP_ID}' \
-H 'x-apideck-consumer-id: {CONSUMER_ID}' \
-H 'x-apideck-service-id: salesforce' \
-d '{"title": "CTO"}'
curl -X DELETE 'https://unify.apideck.com/crm/contacts/contact_123' \
-H 'Authorization: Bearer {API_KEY}' \
-H 'x-apideck-app-id: {APP_ID}' \
-H 'x-apideck-consumer-id: {CONSUMER_ID}' \
-H 'x-apideck-service-id: salesforce'
Apideck uses cursor-based pagination. Pass the next cursor from the response to fetch subsequent pages:
| Parameter | Type | Default | Range |
|-----------|------|---------|-------|
| limit | integer | 20 | 1-200 |
| cursor | string | — | Opaque cursor from meta.cursors.next |
# First page
curl 'https://unify.apideck.com/crm/contacts?limit=50' -H '...'
# Next page
curl 'https://unify.apideck.com/crm/contacts?limit=50&cursor=em9oby1jcm06Om9mZnNldDo6NTA=' -H '...'
When meta.cursors.next is null, you have reached the last page.
?filter[field_name]=value
Available filters vary by resource. Common examples:
| Resource | Filters |
|----------|---------|
| CRM Contacts | filter[name], filter[email], filter[phone_number], filter[company_id], filter[owner_id], filter[first_name], filter[last_name] |
| CRM Opportunities | filter[status], filter[title], filter[company_id], filter[owner_id] |
| Accounting Invoices | filter[updated_since] (ISO 8601 datetime) |
| General | filter[updated_since] for incremental sync |
?sort[by]=updated_at&sort[direction]=desc
?fields=id,name,email,phone_numbers
For connector-specific query parameters not in the unified model:
?pass_through[search]=overdue
For connector-specific fields in request bodies:
{
"first_name": "John",
"pass_through": [
{
"service_id": "salesforce",
"operation_id": "contactsAdd",
"extend_object": {
"custom_sf_field__c": "value"
}
}
]
}
All errors follow this format:
{
"status_code": 400,
"error": "Bad Request",
"type_name": "RequestValidationError",
"message": "Human-readable error description",
"detail": "Parameter-specific info",
"ref": "https://developers.apideck.com/errors#requestvalidationerror"
}
| Code | Meaning | |------|---------| | 400 | Bad Request — invalid parameters | | 401 | Unauthorized — invalid API key | | 402 | Payment Required — API limit reached | | 404 | Not Found — resource does not exist | | 422 | Unprocessable Entity — validation error | | 429 | Too Many Requests — rate limit exceeded | | 5xx | Server Error — Apideck or downstream failure |
Apideck normalizes downstream rate limit headers:
| Header | Description |
|--------|-------------|
| x-downstream-ratelimit-limit | Total request capacity |
| x-downstream-ratelimit-remaining | Remaining requests |
| x-downstream-ratelimit-reset | Unix timestamp when limits reset |
Append ?raw=true to include the unmodified downstream response in a _raw property alongside normalized data.
| API | URL Prefix | Resources |
|-----|-----------|-----------|
| CRM | /crm/ | contacts, companies, leads, opportunities, activities, notes, pipelines, users |
| Accounting | /accounting/ | invoices, bills, payments, customers, suppliers, ledger-accounts, journal-entries, tax-rates, credit-notes, purchase-orders, balance-sheet, profit-and-loss |
| HRIS | /hris/ | employees, companies, departments, payrolls, time-off-requests |
| File Storage | /file-storage/ | files, folders, drives, drive-groups, shared-links, upload-sessions |
| ATS | /ats/ | applicants, applications, jobs |
| Vault | /vault/ | connections, sessions, consumers, custom-mappings, logs |
| Webhook | /webhook/ | webhooks, event-logs |
Events follow the pattern {api}.{resource}.{action}:
crm.contact.created / .updated / .deleted
accounting.invoice.created / .updated / .deleted
hris.employee.created / .updated / .deleted / .terminated
file-storage.file.created / .updated / .deleted
ats.applicant.created / .updated / .deleted
Payload:
{
"payload": {
"event_type": "crm.contact.updated",
"unified_api": "crm",
"service_id": "salesforce",
"consumer_id": "user_abc123",
"entity_id": "contact_123",
"entity_type": "contact",
"occurred_at": "2024-06-15T10:30:00.000Z"
}
}
Verify signatures using the x-apideck-signature header with HMAC-SHA256.
development
Jira Teams via Apideck's Proxy API + managed Vault auth — Apideck handles auth and proxies HTTP calls to Jira Teams's native API. Use when the user wants to call Jira Teams (no unified API resource mapping). Routes through Apideck with serviceId "jira-teams".
development
Jira Service Desk via Apideck's Proxy API + managed Vault auth — Apideck handles auth and proxies HTTP calls to Jira Service Desk's native API. Use when the user wants to call Jira Service Desk (no unified API resource mapping). Routes through Apideck with serviceId "jira-service-desk".
development
Jira Data Center via Apideck's Proxy API + managed Vault auth — Apideck handles auth and proxies HTTP calls to Jira Data Center's native API. Use when the user wants to call Jira Data Center (no unified API resource mapping). Routes through Apideck with serviceId "jira-data-center".
development
JetBrains YouTrack via Apideck's Proxy API + managed Vault auth — Apideck handles auth and proxies HTTP calls to JetBrains YouTrack's native API. Use when the user wants to call JetBrains YouTrack (no unified API resource mapping). Routes through Apideck with serviceId "jetbrains-youtrack".