> 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/core-concepts.md).

# Core Concepts

### Overview

This section explains the fundamental concepts and patterns used throughout our API. Understanding these principles will help you build robust integrations that work efficiently with our platform.

***

### HATEOAS Principles

Our API follows **HATEOAS** (Hypermedia as the Engine of Application State) principles. This means responses include hyperlinks that guide you to related resources, reducing the need to construct URLs manually.

#### Benefits

* **Discoverability** - Navigate the API through links rather than hardcoding URLs
* **Flexibility** - URL structures can evolve without breaking your integration
* **Self-documenting** - Relationships between resources are explicit

#### Link Structure

Every link in our API follows this format:

json

```json
{
  "href": "v1/organization/employees/123"
}
```

**Important:** All `href` values are **relative paths** from the base URL. You need to prepend the base URL to construct the full URL.

**Example:**

```
Base URL: https://api.equipme.io/
Link href: v1/organization/employees/123
Full URL: https://api.equipme.io/v1/organization/employees/123
```

***

### Resource Structures

Our API returns two types of resource representations: **lists** and **detail views**.

#### List Resources

List endpoints return collections of resources with pagination support and navigation links.

**Structure:**

json

```json
{
  "items": [
    {
      "id": 1,
      "name": "Resource 1",
      "self": {
        "href": "/v1/resources/1"
      }
    },
    {
      "id": 2,
      "name": "Resource 2",
      "self": {
        "href": "/v1/resources/2"
      }
    }
  ],
  "total": 150,
  "self": {
    "href": "/v1/resources?limit=100&offset=0"
  },
  "next": {
    "href": "/v1/resources?limit=100&offset=100"
  },
  "previous": null
}
```

**Fields:**

<table><thead><tr><th width="155">Field</th><th width="154">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>items</code></td><td>array</td><td>Array of resource objects</td></tr><tr><td><code>total</code></td><td>integer</td><td>Total number of resources matching the query (across all pages)</td></tr><tr><td><code>self</code></td><td>object</td><td>Link to the current page</td></tr><tr><td><code>next</code></td><td>object</td><td>Link to the next page (null if on last page)</td></tr><tr><td><code>previous</code></td><td>object</td><td>Link to the previous page (null if on first page)</td></tr></tbody></table>

#### Detail Resources

Detail endpoints return a single resource with complete information and links to related resources.

**Structure:**

json

```json
{
    "workplace": {
        "id": 12,
        "name": "HQ",
        "type": "location",
        "self": {
            "href": "v1/organization/locations/12"
        }
    },
    "id": 42,
    "firstName": "John",
    "lastName": "Doe",
    "email": "jd@equipme.io",
    "username": "jd@equipme.io",
    "self": {
        "href": "v1/organization/employees/42"
    }
}
```

**Key characteristics:**

* Every detail resource includes a `self` link pointing to itself
* Related resources include their `id` and basic information
* Related resources include a `self` link for fetching full details
* Collection references (like `items` in the example) include an `href` to the collection endpoint

***

### Pagination

All list endpoints support pagination to handle large datasets efficiently.

#### Parameters

| Parameter | Type    | Required | Default | Description                       |
| --------- | ------- | -------- | ------- | --------------------------------- |
| `limit`   | integer | No       | 100     | Number of items per page (min: 1) |
| `offset`  | integer | No       | 0       | Number of items to skip (min: 0)  |

**Maximum limit:** Varies by endpoint, typically 1000 items per page. Check the specific endpoint documentation for limits.

#### Example Requests

**First page (default):**

```
GET /v1/organization/employees
GET /v1/organization/employees?limit=100&offset=0
```

**Second page:**

```
GET /v1/organization/employees?limit=100&offset=100
```

**Custom page size:**

```
GET /v1/organization/employees?limit=50&offset=0
```

#### Navigating Pages

**Using Navigation Links**

The simplest way to paginate is to follow the `next` and `previous` links in the response.

javascript

```javascript
let currentUrl = '/v1/organization/employees';

while (currentUrl) {
  const response = await fetch(`${baseUrl}${currentUrl}`, {
    headers: { 'X-API-Key': apiKey }
  });
  
  const data = await response.json();
  
  // Process items
  data.items.forEach(item => processItem(item));
  
  // Move to next page
  currentUrl = data.next?.href || null;
}
```

You can also calculate pagination manually.

#### Pagination Best Practices

* **Use consistent page sizes** - Don't change `limit` mid-iteration
* **Follow navigation links** - They handle edge cases automatically
* **Check the `total` field** - Useful for progress indicators and estimating completion time
* **Handle empty pages gracefully** - `items` will be an empty array when no results match

***

### Date Filtering

Many endpoints support date-based filtering to retrieve only new or recently modified resources. This is essential for efficient polling and synchronization.

#### Date Format

All dates must be provided in **ISO 8601 format** with **UTC timezone**:

```
YYYY-MM-DDTHH:MM:SSZ
```

**Examples:**

* `2026-01-15T00:00:00Z` - January 15, 2026 at midnight UTC
* `2026-02-06T14:30:45Z` - February 6, 2026 at 2:30:45 PM UTC

#### Common Date Filter Parameters

The available date filters vary by endpoint, but these are the most common:

<table><thead><tr><th width="155">Parameter</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td><code>after</code></td><td>Resources created/updated after this date</td><td><code>?after=2026-01-01T00:00:00Z</code></td></tr><tr><td><code>before</code></td><td>Resources created/updated before this date</td><td><code>?before=2026-02-01T00:00:00Z</code></td></tr><tr><td><code>createdAfter</code></td><td>Resources created after this date</td><td><code>?createdAfter=2026-01-15T00:00:00Z</code></td></tr><tr><td><code>createdBefore</code></td><td>Resources created before this date</td><td><code>?createdBefore=2026-01-31T23:59:59Z</code></td></tr><tr><td><code>updatedAfter</code></td><td>Resources updated after this date</td><td><code>?updatedAfter=2026-02-01T00:00:00Z</code></td></tr><tr><td><code>updatedBefore</code></td><td>Resources updated before this date</td><td><code>?updatedBefore=2026-02-06T23:59:59Z</code></td></tr></tbody></table>

{% hint style="info" %}
Check the specific endpoint documentation in the API Reference to see which date filters are available for each resource.
{% endhint %}

#### Example Requests

**Get all employees created today:**

```
GET /v1/organization/employees?createdAfter=2026-02-06T00:00:00Z
```

#### Combining Date Filters with Pagination

Date filters work seamlessly with pagination:

```
GET /v1/organization/employees?createdAfter=2026-02-01T00:00:00Z&limit=100&offset=0
```

The `next` and `previous` links will automatically include your date filters (also apply for other optional filters).

***

### Polling Strategy

Date filtering enables efficient polling to keep your system synchronized with our platform.

#### Recommended Polling Pattern

javascript

```javascript
// Store the last sync timestamp
let lastSync = localStorage.getItem('lastSync') || '2026-01-01T00:00:00Z';

async function pollForUpdates() {
  const now = new Date().toISOString();
  
  // Fetch resources updated since last sync
  const response = await fetch(
    `${baseUrl}/v1/organization/employees?createdAfter=${lastSync}`,
    { headers: { 'X-API-Key': apiKey } }
  );
  
  const data = await response.json();
  
  // Process new/updated items
  data.items.forEach(item => {
    updateLocalDatabase(item);
  });
  
  // Handle pagination if needed
  let nextUrl = data.next?.href;
  while (nextUrl) {
    const nextResponse = await fetch(`${baseUrl}${nextUrl}`, {
      headers: { 'X-API-Key': apiKey }
    });
    const nextData = await nextResponse.json();
    
    nextData.items.forEach(item => updateLocalDatabase(item));
    nextUrl = nextData.next?.href;
  }
  
  // Update last sync timestamp
  lastSync = now;
  localStorage.setItem('lastSync', lastSync);
}

// Poll every 5 minutes
setInterval(pollForUpdates, 5 * 60 * 1000);
```

#### Polling Best Practices

* **Use `updatedAfter` filters** - Only fetch resources that have changed
* **Store the last sync timestamp** - Persist it across application restarts
* **Handle pagination** - Changes might span multiple pages
* **Choose appropriate intervals** - Balance freshness vs. API load
  * Real-time needs: Every 1-5 minutes
  * Regular updates: Every 15-30 minutes
  * Batch processing: Hourly or daily
* **Use UTC timestamps** - Avoid timezone-related issues
* **Add a small overlap** - Subtract a few seconds from `lastSync` to account for clock drift

#### Initial Synchronization

For the first sync, you might want to fetch all historical data:

javascript

````javascript
async function initialSync() {
  // Start from a specific date or fetch everything
  const startDate = '2025-01-01T00:00:00Z';
  
  let url = `/v1/organization/employees?createdAfter=${startDate}`;
  
  while (url) {
    const response = await fetch(`${baseUrl}${url}`, {
      headers: { 'X-API-Key': apiKey }
    });
    
    const data = await response.json();
    
    // Process items
    data.items.forEach(item => updateLocalDatabase(item));
    
    // Move to next page
    url = data.next?.href || null;
    
    // Optional: Add progress tracking
    console.log(`Synced ${data.items.length} items, ${data.total} total`);
  }
  
  // Set lastSync to now
  localStorage.setItem('lastSync', new Date().toISOString());
}
```

---

## Data Formats

### Request Format

All request bodies must be **JSON** with the appropriate `Content-Type` header:
```
Content-Type: application/json
````

**Example POST request:**

bash

````bash
curl -X POST "https://api.yourplatform.com/v1/organization/employees" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": 456,
    "items": [
      {
        "productId": 789,
        "quantity": 2
      }
    ]
  }'
```

### Response Format

All responses are **JSON** with this header:
```
Content-Type: application/json; charset=utf-8
````

#### Date and Time Format

* **Format:** ISO 8601 with UTC timezone
* **Pattern:** `YYYY-MM-DDTHH:MM:SSZ`
* **Example:** `2026-02-06T14:30:00Z`

All datetime fields in requests and responses use this format.

#### Null Values

* Missing optional fields are typically omitted from responses
* When explicitly null, fields appear as: `"fieldName": null`
* Empty arrays appear as: `"items": []`
* Empty objects appear as: `"metadata": {}`

***

### Resource Relationships

Resources in our API often reference other resources. We provide links to navigate these relationships efficiently.

#### Embedded References

Some related resources are embedded with basic information:

json

```json
{
    "workplace": {
        "id": 12,
        "name": "HQ",
        "type": "location",
        "self": {
            "href": "v1/organization/locations/12"
        }
    },
    "id": 42,
    "firstName": "John",
    "lastName": "Doe",
    "email": "jd@equipme.io",
    "username": "jd@equipme.io",
    "self": {
        "href": "v1/organization/employees/42"
    }
}
```

To get complete customer details, follow the `self` link:

```
GET /v1/organization/locations/12
```

#### Fetching Related Resources

javascript

```javascript
// Get employee
const employee = await fetch(`${baseUrl}/v1/organization/employees/123`, {
  headers: { 'X-API-Key': apiKey }
}).then(r => r.json());

// Get location details
const location = await fetch(
  `${baseUrl}${employee.workplace.self.href}`,
  { headers: { 'X-API-Key': apiKey } }
).then(r => r.json());
```

***

### Filtering and Sorting

Beyond date filters, many endpoints support additional filtering and sorting options.

#### Common Filter Parameters

Check the API Reference for endpoint-specific filters, but these are commonly available:

| Parameter | Description      | Example          |
| --------- | ---------------- | ---------------- |
| `status`  | Filter by status | `?status=active` |

#### Combining Filters

Multiple filters can be combined:

```
GET /v1/organization/employees?status=active&createdAfter=2026-02-01T00:00:00Z&limit=50
```

#### Sorting

Some endpoints support sorting (check API Reference for availability):

```
GET /v1/organization/employees?sortBy=created&sortOrder=desc
```

### Best Practices

#### Efficient API Usage

1. **Use date filters for polling** - Don't fetch all resources repeatedly
2. **Follow HATEOAS links** - Let the API guide navigation
3. **Respect pagination limits** - Don't request excessive page sizes
4. **Cache when appropriate** - Store stable data locally
5. **Batch requests when possible** - Reduce round trips

#### Handling Changes

1. **Track `updatedAt` timestamps** - Identify what changed since last sync
2. **Handle deletions gracefully** - Deleted resources return `404`
3. **Check status fields** - Resource states can change (e.g., order cancelled)
4. **Verify relationships** - Related resources might be deleted or modified

#### Performance Considerations

1. **Avoid unnecessary detail fetches** - List responses often contain enough information
2. **Parallelize independent requests** - Fetch unrelated resources simultaneously
3. **Use appropriate polling intervals** - Balance freshness vs. load
4. **Implement exponential backoff** - For retry logic on errors

{% hint style="info" %}
**We Value Your Feedback**

We're continuously improving our API based on developer feedback. If you find that:

* Important information is missing from embedded resource references
* You need to make excessive API calls to gather related data
* Specific filters or query parameters would improve your workflow
* Any concept needs better documentation

Please don't hesitate to reach out to our support team. Your input directly influences our API development.
{% endhint %}


---

# 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/core-concepts.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.
