{"name":"SpringRoll API","version":"0.2.0","description":"The Control Plane and App Portal for AI-built Applications. Deploy AI-built applications safely, connect them to approved company data, and make them available to the right people. SpringRoll currently deploys to managed Vercel and Cloudflare. Most agents should use the MCP endpoint instead: it exposes the same control plane as tools with the workflow already encoded.","documentation":{"openapi":"https://springroll.dev/openapi.json","capabilities":"https://springroll.dev/api/v1/capabilities","agentInstructions":"https://springroll.dev/.well-known/agent-instructions.md","llmsTxt":"https://springroll.dev/llms.txt","mcpEndpoint":"https://springroll.dev/api/mcp","mcpServerCard":"https://springroll.dev/.well-known/mcp/server-card.json","humanDocs":"https://springroll.dev/docs"},"authentication":{"preferred":{"method":"oauth2","description":"OAuth 2.1 authorization code with PKCE and RFC 7591 dynamic client registration. Point an MCP client at the endpoint and it discovers the rest. No token is ever pasted.","authorizationServerMetadata":"https://springroll.dev/.well-known/oauth-authorization-server","protectedResourceMetadata":"https://springroll.dev/.well-known/oauth-protected-resource"},"alternative":{"method":"bearer","description":"A SpringRoll agent token, prefixed sbp_, in the Authorization header. Issued to a named membership and carrying exactly that person's permissions. It can never record an approval decision.","header":"Authorization: Bearer sbp_..."},"note":"A tenant id or slug in a URL path is never authorization on its own; it is always verified against the caller's memberships."},"errors":{"description":"Every endpoint answers one envelope. Branch on error.code, never on error.message.","shape":{"error":{"code":"NOT_FOUND","message":"Application 'reporting' was not found.","nextActions":["List applications with GET /api/v1/tenants/{tenant}/apps"],"correlationId":"a-uuid"}}},"manifest":{"apiVersion":"springboard.dev/v1alpha1"},"versioning":{"scheme":"url-path","description":"The major version is the first path segment after /api. A breaking change gets a new segment; within a version, only additive changes are made: new fields, new optional parameters, new endpoints. Treat unknown response fields as forward compatibility, not as an error.","current":"v1","versions":[{"version":"v1","status":"current","basePath":"/api/v1","deprecationDate":null,"sunsetDate":null,"successor":null}],"deprecation":{"noticeDays":365,"description":"A deprecated version keeps answering for at least 365 days after it is announced. From the moment it is deprecated, every response from it carries a Deprecation header (RFC 9745) with the date it was deprecated, a Sunset header (RFC 8594) with the date it stops answering, and a Link header with rel=\"deprecation\" pointing at this policy and rel=\"successor-version\" pointing at what to move to. After the sunset date the version answers 410 Gone with the standard error envelope.","headers":["Deprecation","Sunset","Link"],"policy":"https://springroll.dev/docs/api"},"mcp":{"description":"MCP tool names are versioned by the server version, not by a path. A renamed or removed tool fails on tools/call rather than aliasing silently, because MCP has no deprecation channel for a tool name, and a silent alias would leave an agent using a vocabulary the documentation no longer describes. Read tools/list at the start of a session rather than hard-coding names.","serverCard":"https://springroll.dev/.well-known/mcp/server-card.json"}},"rateLimits":{"description":"Every authenticated response carries the RateLimit headers (both the structured `RateLimit`/`RateLimit-Policy` fields and the `RateLimit-Limit`/`-Remaining`/`-Reset` triplet). A 429 adds Retry-After. Read them and self-throttle rather than retrying blind.","keyedBy":"The authenticated identity where there is one, and the network address otherwise. This prevents one organization behind a shared egress address from exhausting another's budget.","policies":[{"policy":"read","limit":600,"windowSeconds":60},{"policy":"write","limit":120,"windowSeconds":60},{"policy":"deploy","limit":20,"windowSeconds":60},{"policy":"anonymous","limit":30,"windowSeconds":60},{"policy":"oauth-register","limit":10,"windowSeconds":3600},{"policy":"oauth-token","limit":60,"windowSeconds":60},{"policy":"oauth-authorize","limit":30,"windowSeconds":60}],"documentation":"https://springroll.dev/docs/api"},"endpoints":[{"method":"GET","path":"/api/v1","description":"This index.","authenticated":false},{"method":"GET","path":"/api/v1/capabilities","description":"Every MCP tool, and the application manifest contract.","authenticated":false},{"method":"GET","path":"/api/health","description":"Liveness and readiness.","authenticated":false},{"method":"GET","path":"/openapi.json","description":"The OpenAPI 3.1 document for this deployment.","authenticated":false},{"method":"GET","path":"/api/openapi.yaml","description":"The same document as YAML.","authenticated":false},{"method":"POST","path":"/api/mcp","description":"Model Context Protocol, JSON-RPC 2.0 over Streamable HTTP. The primary agent interface.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/apps","description":"List applications.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/apps","description":"Register an application.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/apps/{appId}","description":"Get an application.","authenticated":true},{"method":"PATCH","path":"/api/v1/tenants/{tenant}/apps/{appId}","description":"Update an application.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/apps/{appId}/bundles","description":"List immutable releases.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/apps/{appId}/bundles","description":"Freeze a new release.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/apps/{appId}/deployments","description":"List deployments.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/apps/{appId}/deployments","description":"Deploy a release.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/deployments/{deploymentId}","description":"Get a deployment, including its live URL.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/deployments/{deploymentId}/promote","description":"Promote the same release to the next environment.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/deployments/{deploymentId}/rollback","description":"Roll back an environment.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/apps/{appId}/placement","description":"Where each environment runs, and any pending migration recommendation.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/apps/{appId}/placement","description":"Preview where a deploy would place this application. Works before any provider account is connected.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/migration-recommendations/{recommendationId}","description":"Approve or reject a proposed provider migration. Requires the runtime:manage permission.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/apps/{appId}/approval-requests","description":"List approval requests.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/apps/{appId}/approval-requests","description":"Submit an approval request.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/approval-requests/{requestId}/decisions","description":"Read the decisions on a request.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/approval-requests/{requestId}/decisions","description":"Record a decision. Requires a person; an agent token is refused.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/apps/{appId}/data-access","description":"List governed data grants.","authenticated":true},{"method":"POST","path":"/api/v1/tenants/{tenant}/apps/{appId}/data-access","description":"Request governed data access.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/connectors","description":"List connectors. Credentials are never returned.","authenticated":true},{"method":"GET","path":"/api/v1/tenants/{tenant}/audit-events","description":"Read the append-only audit trail.","authenticated":true},{"method":"GET","path":"/api/data/v1/schema","description":"SpringRoll Connect: the schema a deployed app's grants permit.","authenticated":true},{"method":"POST","path":"/api/data/v1/ask","description":"SpringRoll Connect: query governed data.","authenticated":true},{"method":"POST","path":"/api/data/v1/explain","description":"SpringRoll Connect: what a query would touch, without running it.","authenticated":true}]}