API Overview
Introduction
EverShop is built on a modern API-first architecture, providing developers with powerful and flexible ways to interact with the platform. This approach enables seamless integration with various frontend technologies, third-party systems, and custom applications.
EverShop offers two complementary API approaches:
- RESTful API - For creating, updating, and deleting resources
- GraphQL API - For efficient querying of resources with precise control over returned data
This dual approach combines the simplicity and standardization of REST with the flexibility and efficiency of GraphQL.
For detailed information on API route configuration, refer to our API Routes documentation.
To learn about EverShop's GraphQL implementation, visit our GraphQL API documentation.
API Architecture
REST API
The REST API follows standard RESTful principles with resource-oriented URLs and appropriate HTTP methods. This API is ideal for:
- Creating, updating, and deleting resources
- Standard CRUD operations
- Familiar, predictable patterns for developers
GraphQL API
The GraphQL API provides a single endpoint that accepts complex queries. This API is ideal for:
- Retrieving exactly the data you need, no more or less
- Reducing the number of network requests
- Complex data requirements with nested relationships
There are two GraphQL endpoints, each backed by its own schema:
| Endpoint | Methods | Access | Schema |
|---|---|---|---|
/api/graphql | GET, POST | Public | Storefront schema — excludes admin-only types |
/api/admin/graphql | GET, POST | Private (admin token required) | Full schema, including admin-only types |
Unlike the SSR path — which renders whatever data resolved and logs field errors — these endpoints abort on the first GraphQL error and return an error response rather than partial data.
Store Settings
Store settings live in the database and are written through a single endpoint:
| Endpoint | Method | Access | Description |
|---|---|---|---|
/api/settings | POST | Private | Save one or more store settings. This is what the admin Settings screens call. |
Settings are read back through GraphQL (the setting root), not through a REST endpoint.
Content Types
All API requests and responses use the JSON format. The content type for both requests and responses is application/json.
When sending data to the API, include the following header:
Content-Type: application/json
Localization
REST API paths are never locale-prefixed — there is no /fr/api/.... Storefront endpoints resolve their locale from the X-Locale request header instead:
X-Locale: fr
The header is honoured only when it names a currently enabled locale; anything else (a disabled language, an unknown tag, a malformed value, or no header at all) falls back to the store's default language. This is deliberate — a header must not be able to request an arbitrary or disabled language.
Admin API requests under /api/admin/** ignore X-Locale and always run in the configured admin language.
Authentication
JWT-Based Authentication
EverShop currently implements JWT-based authentication. To authenticate:
- Call the admin token API endpoint
- The API returns a JWT access token and a refresh token
- Include this token in the
AuthorizationBearer header of all subsequent requests requiring authentication
Public Endpoints
Some API endpoints are publicly accessible without authentication. These endpoints are identified by the access property set to public in their respective route.json files. No authentication credentials are required for these endpoints.
HTTP Methods
EverShop's REST API uses standard HTTP methods to perform different actions on resources:
| Method | Description | Idempotent |
|---|---|---|
| GET | Retrieves resources without modifying them | Yes |
| POST | Creates new resources | No |
| PATCH | Updates resources with partial data | Yes |
| DELETE | Removes resources | Yes |
Idempotency
Idempotent methods can be called multiple times with the same effect as calling them once. This is important for reliability and error recovery.
Response Codes
EverShop uses standard HTTP status codes to indicate the result of API requests:
Success Codes
| Code | Description | Common Use Cases |
|---|---|---|
| 200 | OK | Successful GET, PATCH, or DELETE |
| 201 | Created | Successful POST that created a resource |
Client Error Codes
| Status Code | Description | Common Use Cases |
|---|---|---|
| 400 | Bad Request | Invalid input or missing parameters |
| 401 | Unauthorized | Authentication failure |
| 403 | Forbidden | Authenticated but insufficient permissions |
| 404 | Not Found | Resource doesn't exist |
| 405 | Method Not Allowed | HTTP method not supported for endpoint |
| 409 | Conflict | Resource state conflict (e.g., duplicate) |
| 429 | Too Many Requests | Rate limit exceeded — see Rate Limits |
Server Error Codes
| Status Code | Description | Common Use Cases |
|---|---|---|
| 500 | Internal Server Error | Unexpected server-side errors |
Error Handling
When an API request fails, the response will include an error object with details about the failure:
{
"error": {
"status": 500,
"message": "Detailed error message"
}
}
The error object contains:
status: The HTTP status codemessage: A human-readable description of the error
Pagination
For endpoints that return collections of resources, EverShop implements pagination to manage response size:
{
"data": [...],
"links": {
"first": "/api/resource?page=1",
"last": "/api/resource?page=5",
"prev": "/api/resource?page=2",
"next": "/api/resource?page=4"
},
"meta": {
"current_page": 3,
"from": 41,
"last_page": 5,
"path": "/api/resource",
"per_page": 20,
"to": 60,
"total": 100
}
}
Pagination Parameters
| Parameter | Description | Default |
|---|---|---|
| page | Page number to retrieve | 1 |
| limit | Number of items per page | 20 |
Rate Limits
EverShop applies per-client-IP rate limits globally, before any route handling:
| Scope | Limit (per IP) |
|---|---|
/api/** | 120 requests per minute |
| Authentication endpoints — login, registration, and password reset | 8 requests per 15 minutes |
| Page routes (storefront and admin HTML) | ~300 requests per minute |
Static assets and health checks (/health, /healthz) are exempt.
A rejected request returns 429 with the standard error envelope and two headers you should act on:
Retry-After— seconds until the window resets. Wait at least this long before retrying.RateLimit-*— limit, remaining, and reset, so you can throttle before being rejected.
{
"error": {
"status": 429,
"message": "Too many requests. Please slow down and try again later."
}
}
If you are running EverShop behind a reverse proxy or CDN, set the TRUST_PROXY_HOPS environment variable to the number of proxy layers so the limiter sees real client IPs instead of counting all traffic against one address.
Best Practices
- Use HTTPS - Always use secure connections for API requests
- Limit Request Volume - Implement proper caching and throttling mechanisms
- Handle Rate Limiting - Respect
Retry-Afterand theRateLimit-*headers on a 429; do not retry in a tight loop. Budget for 120 req/min on/api/**and 8 attempts per 15 minutes on authentication endpoints. - Send
X-Localefor storefront reads - Localized storefront responses depend on it, and it must name an enabled locale - Validate Input - Always validate request data before sending to the API
- Handle Errors Gracefully - Implement proper error handling in your application