Introduction
Build custom integrations using our API
Authentication
All API endpoints are authenticated using Bearer tokens. Include your API key in the Authorization header of every request:
Authorization: Bearer YOUR_API_KEYAPI Key Types
Buildstash supports two types of API keys, each designed for different use cases:
Workspace API Keys provide access across your entire workspace. Use these for admin tooling, dashboards, or integrations that need to operate across multiple applications.
Application API Keys are scoped to a single application. Use these for CI/CD pipelines, build automation, and any integration that only needs to interact with one specific application. Application keys cannot access other applications in the workspace.
Scopes
Each API key is assigned scopes that control which resources it can access and what actions it can perform. Scopes follow a resource:level pattern (e.g. builds:read, releases:write).
See the Scopes reference for a full breakdown of available scopes and their access levels.
Base URL
All API requests should be made to:
https://app.buildstash.com/api/v1Rate Limiting
Requests are limited per API key, per workspace, and per IP address. Short bursts are allowed, with lower sustained limits per hour and day:
| Limited by | Per minute | Per hour | Per day |
|---|---|---|---|
| API key | 120 | 5,000 | 30,000 |
| Workspace (across all its keys) | 600 | 20,000 | 120,000 |
| IP address | 300 | 10,000 | 60,000 |
Requests for multipart upload part URLs (/upload/request/multipart) are counted separately, with higher limits sized to the largest build your plan allows, so a large upload's parts aren't held back.
Some endpoints also have their own limits. Per application limits apply to requests made with application API keys, and per workspace limits to all requests:
| Endpoints | Per application | Per workspace |
|---|---|---|
| Build and metadata artifact downloads | 30 per minute | 300 per minute |
/upload/request, /upload/verify, /upload/abort | 30 per minute | 60 per minute |
/upload/metadata/request, /upload/metadata/verify | 60 per minute | 120 per minute |
/upload/status | 120 per minute | 360 per minute |
| Webhook test | 5 per minute | 5 per minute |
When rate-limited, the API returns a 429 Too Many Requests response.
If you need higher limits, contact support.
Identifiers
Resources are identified in URLs by the id returned in API responses. Some endpoints also accept a name in place of the ID where noted - for example streams, labels and custom targets can be referenced by ID or name, and platforms and architectures by their identifier (see Data).
Creating and Updating
POSTcreates resources, and performs actions like attaching builds to a release.PATCHupdates a resource. Only the fields you send are changed - send a field asnullto clear it, and leave out fields you don't want to change.PUTis also accepted for these updates, and behaves the same way.PUTon a sub-resource sets that state to exactly what you send, e.g. setting a build's labels replaces all of its labels.DELETEdeletes a resource.
Pagination
List endpoints are paginated. Use per_page (up to 100) and page query parameters, and the pagination object in the response (current_page, per_page, total, last_page, from and to) to page through results.
Errors
The API returns standard HTTP status codes. Error responses include a message field with details:
| Status | Meaning |
|---|---|
400 | Bad request — invalid parameters or business rule violation |
401 | Unauthorized — missing or invalid API key |
403 | Forbidden — insufficient scope or access denied |
404 | Not found — resource does not exist or is not accessible |
409 | Conflict — a resource with this name already exists |
415 | Unsupported media type — Content-Type must be application/json for POST/PUT requests. Uploads also return it when a file's filetype isn't supported on the platform, or a build is too big for your plan |
422 | Validation error — request body failed validation |
429 | Rate limited — too many requests |
500 | Internal server error |