REST API Reference
The Temps REST API is what the dashboard and CLI use: projects, deployments, environments, domains, services, analytics, monitoring, backups and more, as JSON over standard HTTP methods. This page lists the main endpoint groups; the complete spec is served by your own instance.
The auto-generated OpenAPI specification, with every request and response schema, is at /api/api-docs/openapi.json on your Temps instance, with a browsable Swagger UI at /api/swagger-ui. Both require you to be logged in to the dashboard or to send an API key as a Bearer token.
Authentication
All API requests require authentication via a Bearer token in the Authorization header:
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
"https://your-temps-instance/api/projects"
Obtain a token from Settings > API Keys in the dashboard.
Deployed applications receive a per-environment token automatically as the TEMPS_API_TOKEN environment variable.
Base URL
All endpoints are relative to your Temps instance URL:
https://your-temps-instance/api/
Response format
Success responses return JSON with the resource data directly:
{
"id": 1,
"name": "my-project",
"slug": "my-project",
"created_at": "2026-01-15T12:00:00Z"
}
Error responses use RFC 7807 Problem Details (see Errors for status codes and common error types):
{
"type": "about:blank",
"title": "Not Found",
"status": 404,
"detail": "Project 42 not found"
}
Paginated responses return the items under an endpoint-specific key plus a total count. The project list, for example:
{
"projects": [...],
"total": 42,
"page": 1,
"per_page": 10
}
The parameter name and defaults depend on the endpoint: the project and deployment lists take ?page=2&per_page=50 (default 10, max 100), and most other lists take page and page_size (default 20, max 100). See Pagination for the response shapes, sorting, cursor-based endpoints and iterating every page.
Projects
| Method | Endpoint | Description |
|---|---|---|
GET | /projects | List all projects |
POST | /projects | Create a project |
GET | /projects/{project_id} | Get a project |
PUT | /projects/{project_id} | Update a project |
DELETE | /projects/{project_id} | Delete a project |
POST | /projects/{project_id}/trigger-pipeline | Trigger a deployment from Git |
Trigger pipeline
curl -X POST "https://your-instance/api/projects/{project_id}/trigger-pipeline" \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"branch": "main", "environment_id": 1}'
Deployments
| Method | Endpoint | Description |
|---|---|---|
GET | /projects/{project_id}/deployments | List deployments |
GET | /projects/{project_id}/deployments/{deployment_id} | Get deployment details |
POST | /projects/{project_id}/deployments/{deployment_id}/rollback | Rollback to this deployment |
POST | /projects/{project_id}/deployments/{deployment_id}/cancel | Cancel a running deployment |
POST | /projects/{project_id}/deployments/{deployment_id}/pause | Pause a deployment |
POST | /projects/{project_id}/deployments/{deployment_id}/resume | Resume a paused deployment |
POST | /projects/{project_id}/deployments/{deployment_id}/teardown | Stop and remove containers |
Remote deployment endpoints
| Method | Endpoint | Description |
|---|---|---|
POST | /projects/{id}/environments/{id}/deploy/image | Deploy from a registry image |
POST | /projects/{id}/environments/{id}/deploy/image-upload | Upload and deploy a Docker tarball (max 1 GB) |
POST | /projects/{id}/environments/{id}/deploy/static | Deploy from a static file bundle |
POST | /projects/{id}/upload/static | Upload a static bundle (max 500 MB) |
Deployment jobs and logs
| Method | Endpoint | Description |
|---|---|---|
GET | .../deployments/{id}/jobs | List all jobs for a deployment |
GET | .../deployments/{id}/jobs/{job_id}/logs | Get logs for a specific job |
Container management
| Method | Endpoint | Description |
|---|---|---|
GET | .../environments/{id}/containers | List containers in an environment |
GET | .../containers/{id}/metrics | Get real-time resource metrics |
POST | .../containers/{id}/start | Start a container |
POST | .../containers/{id}/stop | Stop a container |
POST | .../containers/{id}/restart | Restart a container |
Environments
| Method | Endpoint | Description |
|---|---|---|
GET | /projects/{project_id}/environments | List environments |
POST | /projects/{project_id}/environments | Create an environment |
GET | /projects/{project_id}/environments/{env_id} | Get environment details |
PUT | /projects/{project_id}/environments/{env_id}/settings | Update environment settings |
DELETE | /projects/{project_id}/environments/{env_id} | Delete an environment |
Update settings
curl -X PUT "https://your-instance/api/projects/{id}/environments/{id}/settings" \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"cpu_limit": 2000000,
"memory_limit": 1024,
"replicas": 3,
"exposed_port": 8080
}'
cpu_limit is in microcores (1000000 = one core, so 2000000 is two cores) and memory_limit is in megabytes. See Resources.
Environment variables
| Method | Endpoint | Description |
|---|---|---|
GET | /projects/{id}/env-vars | List variables (filter with ?environment_id=X) |
POST | /projects/{id}/env-vars | Create a variable |
PUT | /projects/{id}/env-vars/{var_id} | Update a variable |
DELETE | /projects/{id}/env-vars/{var_id} | Delete a variable |
GET | /projects/{id}/env-vars/{key}/value | Get a single variable value |
Create a variable
curl -X POST "https://your-instance/api/projects/{id}/env-vars" \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "API_KEY",
"value": "secret-value",
"environment_ids": [1, 2],
"include_in_preview": false
}'
Domains
| Method | Endpoint | Description |
|---|---|---|
GET | /projects/{id}/environments/{id}/domains | List domains for an environment |
POST | /projects/{id}/environments/{id}/domains | Add a domain |
DELETE | /projects/{id}/environments/{id}/domains/{domain_id} | Remove a domain |
External services
| Method | Endpoint | Description |
|---|---|---|
GET | /external-services | List all services |
POST | /external-services | Create a service |
GET | /external-services/{id} | Get service details |
PUT | /external-services/{id} | Update a service |
DELETE | /external-services/{id} | Delete a service |
GET | /external-services/{id}/health | Health check |
POST | /external-services/{id}/start | Start a service |
POST | /external-services/{id}/stop | Stop a service |
POST | /external-services/{id}/upgrade | Upgrade Docker image |
POST | /external-services/{id}/projects | Link to a project |
DELETE | /external-services/{id}/projects/{project_id} | Unlink from a project |
GET | /external-services/{id}/projects | List linked projects |
GET | /external-services/{id}/projects/{id}/environment | Get env vars for service+project |
GET | /external-services/types | List available service types |
GET | /external-services/available-containers | List importable Docker containers |
POST | /external-services/import | Import an existing container |
Analytics
The visitors page is driven by two endpoints: a faceted filter source and a paginated visitor list. Both are Postgres-only — they are implemented over the visitor and ip_geolocations tables and never touch the events hypertable, so they stay fast regardless of event volume.
| Method | Endpoint | Description |
|---|---|---|
GET | /analytics/visitors | Paginated list of visitors in a segment |
GET | /analytics/visitor-facets | Top values per dimension for the filter UI |
Visitor facets
GET /analytics/visitor-facets returns, in a single response, the top values for exactly five visitor-row dimensions: country, region, city, channel, and referrer. Each dimension is aggregated against the current segment with that dimension's own filter removed, so a selected value never collapses its own dropdown.
{
"country": [{ "value": "United States", "code": "US", "count": 1234 }],
"region": [{ "value": "California", "code": null, "count": 512 }],
"city": [{ "value": "San Francisco", "code": null, "count": 318 }],
"channel": [{ "value": "Organic Search", "code": null, "count": 980 }],
"referrer": [{ "value": "google.com", "code": null, "count": 640 }]
}
Each value is a { value, code, count } object where count is the distinct visitor count in the current segment. The code field carries a 2-letter ISO country code only for the country dimension (so the UI can render a flag); it is null for every other dimension. A null referrer is encoded as the literal string "Direct".
| Query param | Type | Default | Notes |
|---|---|---|---|
start_date | datetime | — | Required |
end_date | datetime | — | Required |
project_id | integer | — | Required |
environment_id | integer | — | Optional |
include_crawlers | boolean | false | Include crawler traffic |
has_activity_only | boolean | true | Only visitors with activity |
per_facet_limit | integer | 50 | Top N values per dimension, clamped to 1–200 |
filter_country | string | — | Active segment filter |
filter_region | string | — | Active segment filter |
filter_city | string | — | Active segment filter |
filter_channel | string | — | Active segment filter |
filter_referrer | string | — | Active segment filter (use Direct for null) |
Segment drill-down
Selecting a facet value sets a segment filter that is passed to GET /analytics/visitors. That endpoint accepts only the same five segment filter params — filter_country, filter_region, filter_city, filter_channel, filter_referrer — alongside limit/offset pagination, and returns a VisitorsResponse with the matching visitors plus a total_count:
curl "https://your-instance/api/analytics/visitors?project_id=1&start_date=2026-05-01T00:00:00Z&end_date=2026-05-29T00:00:00Z&filter_country=United%20States&limit=50&offset=0" \
-H "Authorization: Bearer TOKEN"
{
"visitors": [/* VisitorInfo */],
"total_count": 1234
}
Visitor facets and segment filters cover visitor-row dimensions only. There are no event-side filters (event, browser, OS, device, language, UTM) on these endpoints — those were removed so the queries never hit the events hypertable, which dropped the facets endpoint from roughly 1 s to roughly 15–20 ms at 150k events.
Monitoring
| Method | Endpoint | Description |
|---|---|---|
GET | /projects/{id}/status | Overall status (monitors + incidents) |
POST | /projects/{id}/monitors | Create a monitor |
GET | /projects/{id}/monitors | List monitors |
GET | /monitors/{id} | Get monitor details |
DELETE | /monitors/{id} | Delete a monitor |
GET | /monitors/{id}/current-status | Current status with custom timeframe |
GET | /monitors/{id}/uptime | Uptime history |
GET | /monitors/{id}/bucketed | Time-bucketed status data |
POST | /projects/{id}/incidents | Create an incident |
GET | /projects/{id}/incidents | List incidents |
GET | /incidents/{id} | Get incident details |
PATCH | /incidents/{id}/status | Update incident status |
GET | /incidents/{id}/updates | Get incident updates |
Backups
| Method | Endpoint | Description |
|---|---|---|
GET | /backups/s3-sources | List S3 sources |
POST | /backups/s3-sources | Create an S3 source |
GET | /backups/s3-sources/{id} | Get S3 source |
PATCH | /backups/s3-sources/{id} | Update S3 source |
DELETE | /backups/s3-sources/{id} | Delete S3 source |
POST | /backups/s3-sources/{id}/run | Trigger a manual backup |
GET | /backups/s3-sources/{id}/backups | List backups in this source |
GET | /backups/schedules | List backup schedules |
POST | /backups/schedules | Create a schedule |
GET | /backups/schedules/{id} | Get schedule |
DELETE | /backups/schedules/{id} | Delete schedule |
PATCH | /backups/schedules/{id}/enable | Enable schedule |
PATCH | /backups/schedules/{id}/disable | Disable schedule |
GET | /backups/{id} | Get backup details |
Notifications
| Method | Endpoint | Description |
|---|---|---|
GET | /notification-providers | List providers |
POST | /notification-providers/email | Create email provider |
POST | /notification-providers/slack | Create Slack provider |
POST | /notification-providers/webhook | Create webhook provider |
PUT | /notification-providers/email/{id} | Update email provider |
PUT | /notification-providers/slack/{id} | Update Slack provider |
PUT | /notification-providers/webhook/{id} | Update webhook provider |
DELETE | /notification-providers/{id} | Delete provider |
POST | /notification-providers/{id}/test | Test provider |
GET | /notification-preferences | Get preferences |
PUT | /notification-preferences | Update preferences |
Webhooks
| Method | Endpoint | Description |
|---|---|---|
GET | /projects/{id}/webhooks | List webhooks |
POST | /projects/{id}/webhooks | Create a webhook |
GET | /projects/{id}/webhooks/{id} | Get webhook |
PUT | /projects/{id}/webhooks/{id} | Update webhook |
DELETE | /projects/{id}/webhooks/{id} | Delete webhook |
GET | /projects/{id}/webhooks/{id}/deliveries | List delivery history |
POST | .../deliveries/{id}/retry | Retry a failed delivery |
Users and API keys
| Method | Endpoint | Description |
|---|---|---|
GET | /users | List users |
POST | /users | Create a user |
GET | /users/{id} | Get user |
PUT | /users/{id} | Update user |
DELETE | /users/{id} | Delete user |
GET | /api-keys | List API keys |
POST | /api-keys | Create an API key |
DELETE | /api-keys/{id} | Delete an API key |
For the complete, auto-generated OpenAPI specification with all request/response schemas, fetch /api/api-docs/openapi.json on your Temps instance (or browse it at /api/swagger-ui). The Node SDK (@temps-sdk/node-sdk) provides a fully typed client with 24 namespaces generated from this spec.
More APIs
Some features have their own reference pages:
| Feature | Reference |
|---|---|
| OpenAI-compatible AI gateway | AI Gateway |
| Isolated sandboxes for running code | Sandboxes |
| Routes to services Temps doesn't deploy | Reverse Proxy Routes |
| MCP servers for agents in a sandbox | MCP Servers |
| Outbound event notifications | Webhooks |
Using the Node SDK
Instead of making raw HTTP requests, use the official Node SDK for a typed client:
import { TempsClient } from '@temps-sdk/node-sdk';
const temps = new TempsClient({
baseUrl: 'https://temps.example.com',
apiKey: 'your-api-key',
});
// All endpoints are available as typed methods
const { data: projects } = await temps.projects.list();
const { data: deployments } = await temps.deployments.list({ path: { project_id: 1 } });
See the Node SDK Reference for the full API.