API Design Guide
Our API design principles and conventions. Following REST best practices with predictable, consistent patterns.
Design Principles
Use Nouns for Resources
Resource endpoints should be nouns, not verbs. HTTP methods convey the action.
GET /v1/valuationsGET /v1/getValuationsPlural Resource Names
Use plural nouns for collections to maintain consistency.
GET /v1/productsGET /v1/productHierarchical Resources
Express relationships through URL hierarchy.
GET /v1/organizations/{org}/membersGET /v1/members?org_id={org}Consistent Naming
Use snake_case for JSON fields, kebab-case for URLs.
{ "created_at": "..." }{ "createdAt": "..." }HTTP Methods
| Method | Usage | Idempotent | Safe |
|---|---|---|---|
| GET | Retrieve resource(s) | ||
| POST | Create new resource | — | — |
| PUT | Full resource update | — | |
| PATCH | Partial resource update | — | — |
| DELETE | Remove resource | — |
Response Structure
All responses follow a consistent envelope structure with data, meta, and links.
// Successful response
{
"data": {
"id": "val_abc123",
"object": "valuation",
"created_at": "2024-12-15T10:30:00Z",
"status": "completed",
// ... resource fields
},
"meta": {
"request_id": "req_xyz789",
"processing_time_ms": 127
}
}
// List response with pagination
{
"data": [
{ "id": "val_abc123", ... },
{ "id": "val_def456", ... }
],
"meta": {
"total": 156,
"page": 1,
"per_page": 20,
"has_more": true
},
"links": {
"self": "/v1/valuations?page=1",
"next": "/v1/valuations?page=2",
"last": "/v1/valuations?page=8"
}
}
// Error response
{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid",
"message": "The 'condition' field must be one of: new, like_new, good, fair, poor",
"param": "condition",
"doc_url": "https://docs.justkalm.com/errors#parameter_invalid"
},
"meta": {
"request_id": "req_xyz789"
}
}Naming Conventions
Consistent naming patterns across all endpoints and fields.
# Resource identifiers
val_abc123xyz # Valuation ID (prefixed)
prod_def456uvw # Product ID
org_ghi789rst # Organization ID
# Timestamps (always ISO 8601 with timezone)
{
"created_at": "2024-12-15T10:30:00Z",
"updated_at": "2024-12-15T14:45:30Z",
"expires_at": "2025-01-15T00:00:00Z"
}
# Boolean fields (use is_, has_, can_ prefixes)
{
"is_active": true,
"has_certificate": false,
"can_resell": true
}
# Enums (lowercase, snake_case)
{
"status": "pending_review",
"condition": "like_new",
"category": "luxury_handbags"
}Versioning Philosophy
We use URL-based versioning for clarity and ease of use.
# URL-based versioning (our approach) GET /v1/valuations GET /v2/valuations # When major breaking changes # Version negotiation via headers (alternative) Accept: application/vnd.justkalm.v1+json # Why we chose URL versioning: # - Explicit and visible # - Easy to test in browser # - Clear deprecation path # - Cacheable by CDN
Best Practices
Use Idempotency Keys
Always include X-Idempotency-Key for POST requests to safely retry on network failures.
Request Field Selection
Use ?fields=id,status,value to reduce payload size and improve performance.
Handle Pagination
Use cursor-based pagination for large datasets. Followlinks.next for navigation.
Log Request IDs
Store X-Request-Id from responses for debugging and support requests.