> For the complete documentation index, see [llms.txt](https://hub.equipme.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hub.equipme.io/development/working-with-the-api.md).

# Working with the API

### Overview

This section covers practical patterns and best practices for building robust integrations with our API. You'll learn how to handle common scenarios, respect rate limits, and build efficient polling mechanisms.

***

### Request and Response Patterns

#### Standard Request Structure

All API requests follow a consistent pattern:

```
[METHOD] https://api.equipme.io/v1/[resource]
Headers:
  X-API-Key: your_api_key_here
  Content-Type: application/json (for POST/PUT/PATCH)
Body: (JSON for POST/PUT/PATCH requests)
```

#### HTTP Methods

Our API uses standard HTTP methods with their conventional semantics:

<table><thead><tr><th width="104">Method</th><th width="218">Purpose</th><th width="141">Request Body</th><th width="143">Response Body</th><th>Idempotent</th></tr></thead><tbody><tr><td><code>GET</code></td><td>Retrieve resource(s)</td><td>No</td><td>Yes</td><td>Yes</td></tr><tr><td><code>POST</code></td><td>Create new resource</td><td>Yes</td><td>Yes (created resource)</td><td>No</td></tr><tr><td><code>PUT</code></td><td>Replace entire resource</td><td>Yes</td><td>Usually No</td><td>Yes</td></tr><tr><td><code>PATCH</code></td><td>Update specific fields</td><td>Yes</td><td>Usually No</td><td>Usually yes</td></tr><tr><td><code>DELETE</code></td><td>Remove resource</td><td>Usually No</td><td>Usually No</td><td>Yes</td></tr></tbody></table>

**Idempotent** means making the same request multiple times produces the same result as making it once.

{% hint style="info" %}
**PUT vs PATCH:** We're transitioning from PUT to PATCH for updates. PUT endpoints require you to send the complete resource (all fields), while PATCH allows partial updates using JSON Patch operations. Check the API Reference for which method each endpoint supports.
{% endhint %}

#### Successful Responses

<table><thead><tr><th width="171">Status Code</th><th>When Used</th><th>Response Body</th></tr></thead><tbody><tr><td><code>200 OK</code></td><td>Successful GET</td><td>Resource data</td></tr><tr><td><code>201 Created</code></td><td>Successful POST</td><td>Created resource including <code>id</code></td></tr><tr><td><code>204 No Content</code></td><td>Successful DELETE or update with no return data</td><td>Empty</td></tr></tbody></table>

#### PATCH Requests with JSON Patch

For PATCH operations, we use the [JSON Patch standard (RFC 6902)](https://datatracker.ietf.org/doc/html/rfc6902/). This allows you to precisely specify which fields to update without sending the entire resource.

**Content-Type for PATCH requests:**

```
Content-Type: application/json-patch+json
```

**Common JSON Patch operations:**

<table><thead><tr><th width="142">Operation</th><th>Purpose</th><th>Example</th></tr></thead><tbody><tr><td><code>add</code></td><td>Add a new field or array element</td><td>Add an employee as manager</td></tr><tr><td><code>remove</code></td><td>Remove a field or array element</td><td>Clear a phone number</td></tr><tr><td><code>replace</code></td><td>Change a field's value</td><td>Update employee email address</td></tr></tbody></table>

**Example PATCH request body:**

json

```json
[
  {
    "op": "replace",
    "path": "/status",
    "value": "active"
  },
  {
    "op": "replace",
    "path": "/email",
    "value": "john@equipme.io"
  }
]
```

**Benefits of JSON Patch:**

* Send only the changes, not the entire resource
* Reduce bandwidth and processing overhead
* Support complex operations like array manipulation

See the API Reference for specific examples of PATCH operations for each endpoint.

***

### Rate Limits

To ensure fair usage and platform stability, our API implements rate limiting.

#### Current Rate Limits

| Request Type       | Limit         | Window     |
| ------------------ | ------------- | ---------- |
| POST requests      | 100 requests  | per second |
| All other requests | 1000 requests | per minute |

{% hint style="info" %}
Rate limits apply per unique endpoint path with the same parameters. Different resource IDs are treated as separate endpoints.

Example:

* `/v1/organization/employees/1` - 1000 requests/minute
* `/v1/organization/employees/2` - 1000 requests/minute (separate limit)
  {% endhint %}

#### Rate Limit Headers

Every successful API response includes headers indicating your current rate limit status:

```
X-Rate-Limit-Limit: 1000
X-Rate-Limit-Remaining: 847
X-Rate-Limit-Reset: 2026-02-06T12:14:12.5987061Z
```

<table><thead><tr><th width="257">Header</th><th>Description</th></tr></thead><tbody><tr><td><code>X-Rate-Limit-Limit</code></td><td>Maximum requests allowed in the window</td></tr><tr><td><code>X-Rate-Limit-Remaining</code></td><td>Requests remaining in current window</td></tr><tr><td><code>X-Rate-Limit-Reset</code></td><td>Timestamp when the limit resets</td></tr></tbody></table>

#### Rate Limit Exceeded

When you exceed the rate limit, the API returns:

**Status Code:** `429 Too Many Requests`

**Headers:**

```
Retry-After: 45
```

The `Retry-After` header indicates how many seconds to wait before retrying.

**Example error response:**

json

```json
{
  "errorCode": "TooManyRequests",
  "errorDescription": "API calls quota exceeded! Maximum admitted 1000 per 1m."
}
```

#### Handling Rate Limits

**Best Practices**

1. **Monitor rate limit headers proactively** - Check `X-Rate-Limit-Remaining` in your responses to anticipate when you'll hit the limit
2. **Implement exponential backoff** - When you receive a 429 response, wait the time specified in `Retry-After` (or use exponential backoff for other errors)
3. **Use request queuing** - For applications making many requests, implement a queue that controls the request rate to stay below limits
4. **Respect the `Retry-After` header** - Always honor the wait time specified by the server
5. **Distribute requests over time** - Avoid sending bursts of requests; spread them evenly across the time window
6. **Cache stable data** - Don't repeatedly fetch resources that rarely change
7. **Use date filters for polling** - Only fetch resources that have changed since your last sync
8. **Consider separate API keys** - Use different keys for independent services to isolate their rate limits

***

### Common Integration Patterns

#### Pattern 1: Initial Data Synchronization

When setting up a new integration, you'll need to fetch all existing data:

**Approach:**

1. Start with the first page of the list endpoint
2. Process the items (store in your database, etc.)
3. Follow the `next` link to retrieve the next page
4. Repeat until `next` is null
5. Store the current timestamp for future incremental updates

**Considerations:**

* Add small delays between pages to respect rate limits
* Track progress (items processed vs. total) for monitoring
* Handle interruptions gracefully (store last successfully processed page)

#### Pattern 2: Incremental Updates (Polling)

After initial synchronization, regularly check for changes:

**Approach:**

1. Retrieve your last sync timestamp
2. Make a request with `updatedAfter` filter using that timestamp
3. Process all pages of changed resources
4. Update your local data store
5. Store the current timestamp as the new "last sync"

**Best Practices:**

* Choose polling intervals based on your business needs (see table below)
* Use `after/updatedAfter` filters to minimize data transfer
* Handle pagination properly - changes might span multiple pages
* Add a small time overlap (e.g., subtract 1-2 seconds from last sync) to account for potential clock drift

<table><thead><tr><th width="186">Update Frequency</th><th width="201">Recommended Interval</th><th>Use Case</th></tr></thead><tbody><tr><td>Real-time</td><td>1-2 minutes</td><td>Critical order updates</td></tr><tr><td>Regular</td><td>30-60 minutes</td><td>General synchronization</td></tr><tr><td>Periodic</td><td>2-24 hours</td><td>Historical data, reports, re-sync</td></tr></tbody></table>

#### Pattern 3: Bulk Operations

When you need to create or update many resources:

**Considerations:**

* Implement request queuing to respect rate limits (especially the limit for POST requests)
* Process items in batches with delays between batches
* Track successes and failures separately
* Implement retry logic for failed operations
* Provide progress indicators for long-running operations

**Error Handling:**

* Don't stop the entire batch on first error
* Collect all failures for review
* Log failures with context for debugging
* Consider implementing a dead-letter queue for problematic items

#### Pattern 4: Detecting Deletions

The API returns 404 for deleted resources, but how do you detect deletions during polling?

**Approach 1: Full reconciliation (periodic)**

* Periodically fetch all resource IDs from the API
* Compare with your local database
* Mark resources missing from API as deleted

**Approach 2: Handle 404s during detail fetches**

* When fetching specific resources that return 404, mark them as deleted or inaccessible
* Note: 404 could mean deleted OR no access due to permissions

***

### Error Handling Strategies

All API integrations should implement robust error handling to deal with various failure scenarios. Our API uses standard HTTP status codes and provides detailed error responses to help you diagnose and resolve issues.

**Key principles:**

* Always check HTTP status codes before processing responses
* Implement retry logic for transient errors (rate limits, server errors)
* Don't retry authentication or business logic errors
* Log errors with sufficient context for debugging

For comprehensive information on error handling, including:

* Complete error response format
* All error codes and their meanings
* Retry strategies and exponential backoff patterns
* Troubleshooting guides for common issues

See the [**Error Handling**](/development/error-handling.md) chapter.

***

### Performance Optimization

#### Minimize Unnecessary Requests

**Strategies:**

* Use list responses when they contain sufficient data; don't fetch details unnecessarily
* Cache stable resources (employee profiles that rarely change)
* Batch related operations when possible
* Use date filters to fetch only changed data

***

### Testing Your Integration

#### Testing Checklist

Before deploying your integration to production, verify:

* [ ] **Authentication works** - API key is valid and requests succeed
* [ ] **Error handling** - Application handles all error types gracefully
* [ ] **Rate limiting** - Retry logic works correctly for 429 responses
* [ ] **Pagination** - All pages are fetched correctly; navigation links work
* [ ] **Date filtering** - Polling correctly fetches only changed data
* [ ] **Network failures** - Timeouts and connection errors are handled
* [ ] **Empty responses** - Application handles zero results correctly
* [ ] **Large datasets** - System handles maximum pagination limits
* [ ] **Concurrent requests** - Thread safety if using parallel requests
* [ ] **Deleted resources** - 404 responses handled appropriately
* [ ] **JSON Patch operations** - PATCH requests formatted correctly

***

#### Debugging Tips

**Common issues and solutions:**

1. **Intermittent 401 errors** - Check if API key has expiration date
2. **Slow requests** - Check network latency; consider geographic location
3. **Missing data in polls** - Verify date filter includes correct timezone (UTC)
4. **Pagination stops early** - Check if you're properly following `next` links
5. **Rate limit hits** - Monitor `X-Rate-Limit-Remaining`; implement request queuing


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hub.equipme.io/development/working-with-the-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
