> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API Design Guidelines

> Best practices and standards for StateSet API development

# StateSet API Design Guidelines

This document outlines the design principles, patterns, and best practices for the StateSet API. Following these guidelines ensures consistency, usability, and maintainability across all API endpoints.

## Core Principles

### 1. RESTful Design

* Use standard HTTP methods appropriately:
  * `GET` for retrieving resources
  * `POST` for creating resources
  * `PUT/PATCH` for updating resources
  * `DELETE` for removing resources

### 2. Resource-Oriented URLs

```
Good:
GET    /v1/orders
GET    /v1/orders/{id}
POST   /v1/orders
PUT    /v1/orders/{id}
DELETE /v1/orders/{id}

Avoid:
GET    /v1/getOrders
POST   /v1/createOrder
POST   /v1/orders/update
```

### 3. Consistent Naming Conventions

* Use lowercase with hyphens for URLs: `/v1/work-orders`
* Use camelCase for JSON properties: `firstName`, `createdAt`
* Use snake\_case for query parameters: `created_after`, `sort_by`
* Pluralize collection endpoints: `/orders` not `/order`

## Request Standards

### Headers

Required headers for all requests:

```http theme={null}
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Accept: application/json
```

Optional headers:

```http theme={null}
X-API-Version: 2024-01-01
X-Idempotency-Key: unique-request-id
X-Request-ID: client-generated-id
Accept-Language: en-US
```

### Query Parameters

#### Pagination

All list endpoints must support:

```
GET /v1/orders?limit=20&offset=0
GET /v1/orders?limit=20&cursor=eyJpZCI6MTAwfQ==
```

Default pagination:

* `limit`: 20 (max: 100)
* `offset`: 0

#### Filtering

Use consistent filter patterns:

```
# Exact match
GET /v1/orders?status=shipped

# Multiple values
GET /v1/orders?status_in=shipped,delivered

# Range queries
GET /v1/orders?created_after=2024-01-01T00:00:00Z
GET /v1/orders?created_before=2024-12-31T23:59:59Z
GET /v1/orders?amount_gte=10000
GET /v1/orders?amount_lte=50000

# Search
GET /v1/orders?search=john+doe
GET /v1/orders?customer_email=john@example.com
```

#### Sorting

```
GET /v1/orders?sort=created_at&order=desc
GET /v1/orders?sort=-created_at  # Alternative: prefix with - for desc
```

### Request Body

#### Required Fields

Clearly mark required fields in documentation:

```json theme={null}
{
  "customer": {       // required
    "email": "...",   // required
    "name": "..."     // optional
  }
}
```

#### Nested Objects

Use nested objects for logical grouping:

```json theme={null}
{
  "customer": {
    "email": "john@example.com",
    "first_name": "John",
    "last_name": "Doe"
  },
  "shipping_address": {
    "line1": "123 Main St",
    "city": "San Francisco",
    "state": "CA",
    "postal_code": "94105",
    "country": "US"
  }
}
```

## Response Standards

### Success Responses

#### Single Resource

```json theme={null}
{
  "id": "ord_1a2b3c4d",
  "object": "order",
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-15T10:30:00Z",
  // ... resource fields
}
```

#### Collection

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "ord_1a2b3c4d",
      "object": "order",
      // ... resource fields
    }
  ],
  "has_more": true,
  "total_count": 150,
  "url": "/v1/orders"
}
```

#### With Metadata

```json theme={null}
{
  "data": {
    "id": "ord_1a2b3c4d",
    "object": "order",
    // ... resource fields
  },
  "meta": {
    "request_id": "req_xyz789",
    "version": "v1",
    "timestamp": "2024-01-15T10:30:00Z"
  }
}
```

### Error Responses

#### Standard Error Format

```json theme={null}
{
  "error": {
    "type": "validation_error",
    "code": "VALIDATION_ERROR",
    "message": "Invalid request parameters",
    "details": {
      "field_errors": {
        "email": "Invalid email format",
        "quantity": "Must be a positive integer"
      }
    },
    "documentation_url": "https://docs.stateset.com/errors/VALIDATION_ERROR",
    "request_id": "req_xyz789"
  }
}
```

#### HTTP Status Codes

| Status                    | Usage                                   |
| ------------------------- | --------------------------------------- |
| 200 OK                    | Successful GET, PUT, PATCH              |
| 201 Created               | Successful POST creating resource       |
| 202 Accepted              | Request accepted for async processing   |
| 204 No Content            | Successful DELETE                       |
| 400 Bad Request           | Invalid request parameters              |
| 401 Unauthorized          | Missing or invalid authentication       |
| 403 Forbidden             | Valid auth but insufficient permissions |
| 404 Not Found             | Resource doesn't exist                  |
| 409 Conflict              | Resource conflict (e.g., duplicate)     |
| 422 Unprocessable Entity  | Validation errors                       |
| 429 Too Many Requests     | Rate limit exceeded                     |
| 500 Internal Server Error | Server error                            |
| 503 Service Unavailable   | Temporary unavailability                |

## Data Types and Formats

### Timestamps

Always use ISO 8601 format with timezone:

```json theme={null}
{
  "created_at": "2024-01-15T10:30:00Z",
  "scheduled_for": "2024-01-20T14:00:00-08:00"
}
```

### Money/Currency

Store monetary values in smallest currency unit (cents):

```json theme={null}
{
  "amount": 1999,  // $19.99
  "currency": "USD"
}
```

### Phone Numbers

Use E.164 format:

```json theme={null}
{
  "phone": "+14155551234"
}
```

### Countries and States

Use ISO standards:

* Countries: ISO 3166-1 alpha-2 (US, CA, GB)
* States/Provinces: ISO 3166-2 (CA-ON, US-NY)

```json theme={null}
{
  "country": "US",
  "state": "CA"
}
```

## Versioning

### URL Versioning

Primary versioning method:

```
https://api.stateset.com/v1/orders
https://api.stateset.com/v2/orders
```

### Header Versioning

For minor versions:

```http theme={null}
X-API-Version: 2024-01-01
```

### Deprecation Process

1. Announce deprecation with 90-day notice
2. Add deprecation headers:
   ```http theme={null}
   Sunset: Sat, 31 Dec 2024 23:59:59 GMT
   Deprecation: true
   Link: <https://api.stateset.com/v2/orders>; rel="successor-version"
   ```
3. Maintain deprecated version for minimum 12 months

## Idempotency

### Implementation

Support idempotency for all POST, PUT, PATCH requests:

```http theme={null}
POST /v1/orders
X-Idempotency-Key: unique-request-id-123
```

Response includes:

```http theme={null}
X-Idempotency-Key: unique-request-id-123
X-Idempotent-Replayed: true
```

## Webhooks

### Event Naming

Use dot notation for event types:

```
order.created
order.updated
order.shipped
order.delivered
return.requested
return.approved
payment.succeeded
payment.failed
```

### Webhook Payload

```json theme={null}
{
  "id": "evt_1a2b3c4d",
  "type": "order.created",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "object": {
      "id": "ord_xyz789",
      "object": "order",
      // ... full object
    },
    "previous_attributes": {
      // ... for update events
    }
  },
  "request": {
    "id": "req_abc123",
    "idempotency_key": "unique-key-123"
  }
}
```

### Security

Always include signature header:

```http theme={null}
X-StateSet-Signature: sha256=3f3b3c4d...
```

## Performance Guidelines

### Response Times

Target response times:

* Simple reads: \< 200ms
* Complex queries: \< 500ms
* Writes: \< 1000ms

### Payload Size

* Limit response size to 1MB
* Use pagination for large collections
* Support field filtering:
  ```
  GET /v1/orders?fields=id,status,customer
  ```

### Caching

Include cache headers:

```http theme={null}
Cache-Control: private, max-age=300
ETag: "33a64df551"
Last-Modified: Wed, 15 Jan 2024 10:30:00 GMT
```

## GraphQL Guidelines

### Query Naming

```graphql theme={null}
# Good
query GetOrder($id: ID!) {
  order(id: $id) {
    id
    status
  }
}

# Avoid
query fetchOrderData($id: ID!) {
  getOrderById(id: $id) {
    id
    status
  }
}
```

### Mutations

```graphql theme={null}
mutation CreateOrder($input: OrderCreateInput!) {
  orderCreate(input: $input) {
    order {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}
```

### Error Handling

Return errors in userErrors field:

```json theme={null}
{
  "data": {
    "orderCreate": {
      "order": null,
      "userErrors": [
        {
          "field": "customer.email",
          "message": "Email is required"
        }
      ]
    }
  }
}
```

## Testing

### Test Coverage

All endpoints must include:

* Success path tests
* Error handling tests
* Edge case tests
* Performance tests

### Example Test Cases

```javascript theme={null}
describe('POST /v1/orders', () => {
  test('creates order successfully', async () => {
    const response = await api.post('/v1/orders', validOrderData);
    expect(response.status).toBe(201);
    expect(response.body.object).toBe('order');
  });

  test('returns 400 for invalid data', async () => {
    const response = await api.post('/v1/orders', invalidOrderData);
    expect(response.status).toBe(400);
    expect(response.body.error.code).toBe('VALIDATION_ERROR');
  });

  test('handles idempotency', async () => {
    const key = 'test-idempotency-key';
    const response1 = await api.post('/v1/orders', data, {
      headers: { 'X-Idempotency-Key': key }
    });
    const response2 = await api.post('/v1/orders', data, {
      headers: { 'X-Idempotency-Key': key }
    });
    expect(response1.body.id).toBe(response2.body.id);
  });
});
```

## Documentation Requirements

Every endpoint must document:

1. **Description**: Clear explanation of what the endpoint does
2. **Authentication**: Required permissions
3. **Parameters**: All query params, headers, and body fields
4. **Response**: Success and error response formats
5. **Examples**: Working code examples in multiple languages
6. **Rate Limits**: Specific limits if different from defaults
7. **Webhooks**: Related webhook events
8. **See Also**: Links to related endpoints

## Security Best Practices

1. **Always use HTTPS**
2. **Validate all inputs** - Never trust client data
3. **Rate limit all endpoints**
4. **Log security events** - Failed auth, permission denials
5. **Sanitize outputs** - Prevent XSS in responses
6. **Use secure headers**:
   ```http theme={null}
   X-Content-Type-Options: nosniff
   X-Frame-Options: DENY
   X-XSS-Protection: 1; mode=block
   ```

## Monitoring and Observability

Include correlation IDs in all requests:

```http theme={null}
X-Request-ID: client-generated-uuid
X-Correlation-ID: server-generated-uuid
```

Log format:

```json theme={null}
{
  "timestamp": "2024-01-15T10:30:00Z",
  "request_id": "req_abc123",
  "method": "POST",
  "path": "/v1/orders",
  "status": 201,
  "duration_ms": 145,
  "user_id": "usr_xyz789"
}
```

## Change Management

1. **Backwards Compatibility**: Never break existing integrations
2. **Additive Changes**: New fields are safe to add
3. **Deprecation Notices**: Minimum 90 days
4. **Migration Guides**: Provide clear upgrade paths
5. **Changelog**: Maintain detailed changelog

## Contact

For API design questions or to propose changes to these guidelines:

* Email: [api-team@stateset.com](mailto:api-team@stateset.com)
* Slack: #api-design
* GitHub: stateset/api-guidelines
