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.
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
Required headers for all requests:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Accept: application/json
Optional headers:
X-API-Version: 2024-01-01
X-Idempotency-Key: unique-request-id
X-Request-ID: client-generated-id
Accept-Language: en-US
Query Parameters
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:
{
"customer": { // required
"email": "...", // required
"name": "..." // optional
}
}
Nested Objects
Use nested objects for logical grouping:
{
"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
{
"id": "ord_1a2b3c4d",
"object": "order",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
// ... resource fields
}
Collection
{
"object": "list",
"data": [
{
"id": "ord_1a2b3c4d",
"object": "order",
// ... resource fields
}
],
"has_more": true,
"total_count": 150,
"url": "/v1/orders"
}
{
"data": {
"id": "ord_1a2b3c4d",
"object": "order",
// ... resource fields
},
"meta": {
"request_id": "req_xyz789",
"version": "v1",
"timestamp": "2024-01-15T10:30:00Z"
}
}
Error Responses
{
"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 |
Timestamps
Always use ISO 8601 format with timezone:
{
"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):
{
"amount": 1999, // $19.99
"currency": "USD"
}
Phone Numbers
Use E.164 format:
{
"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)
{
"country": "US",
"state": "CA"
}
Versioning
URL Versioning
Primary versioning method:
https://api.stateset.com/v1/orders
https://api.stateset.com/v2/orders
For minor versions:
X-API-Version: 2024-01-01
Deprecation Process
- Announce deprecation with 90-day notice
- Add deprecation headers:
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
Deprecation: true
Link: <https://api.stateset.com/v2/orders>; rel="successor-version"
- Maintain deprecated version for minimum 12 months
Idempotency
Implementation
Support idempotency for all POST, PUT, PATCH requests:
POST /v1/orders
X-Idempotency-Key: unique-request-id-123
Response includes:
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
{
"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:
X-StateSet-Signature: sha256=3f3b3c4d...
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:
Cache-Control: private, max-age=300
ETag: "33a64df551"
Last-Modified: Wed, 15 Jan 2024 10:30:00 GMT
GraphQL Guidelines
Query Naming
# Good
query GetOrder($id: ID!) {
order(id: $id) {
id
status
}
}
# Avoid
query fetchOrderData($id: ID!) {
getOrderById(id: $id) {
id
status
}
}
Mutations
mutation CreateOrder($input: OrderCreateInput!) {
orderCreate(input: $input) {
order {
id
status
}
userErrors {
field
message
}
}
}
Error Handling
Return errors in userErrors field:
{
"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
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:
- Description: Clear explanation of what the endpoint does
- Authentication: Required permissions
- Parameters: All query params, headers, and body fields
- Response: Success and error response formats
- Examples: Working code examples in multiple languages
- Rate Limits: Specific limits if different from defaults
- Webhooks: Related webhook events
- See Also: Links to related endpoints
Security Best Practices
- Always use HTTPS
- Validate all inputs - Never trust client data
- Rate limit all endpoints
- Log security events - Failed auth, permission denials
- Sanitize outputs - Prevent XSS in responses
- Use secure headers:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Monitoring and Observability
Include correlation IDs in all requests:
X-Request-ID: client-generated-uuid
X-Correlation-ID: server-generated-uuid
Log format:
{
"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
- Backwards Compatibility: Never break existing integrations
- Additive Changes: New fields are safe to add
- Deprecation Notices: Minimum 90 days
- Migration Guides: Provide clear upgrade paths
- Changelog: Maintain detailed changelog
For API design questions or to propose changes to these guidelines: