{"openapi": "3.1.0", "info": {"title": "Synsema Platform API", "version": "0.1.0", "description": "Deploy Synsema agents under a capability ceiling. Every /api/v1 route takes `Authorization: Bearer <token>`; get a token with POST /api/v1/auth/login or from Settings in the dashboard."}, "servers": [{"url": "https://control-1.synsema.com"}], "paths": {"/api/v1/auth/login": {"post": {"summary": "Exchange email and password for an API token", "responses": {"200": {"description": "{token, user}"}}, "parameters": [], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"email": {"type": "string", "description": "string"}, "password": {"type": "string", "description": "string"}}}}}}}}, "/api/v1/me": {"get": {"summary": "The account behind the token", "responses": {"200": {"description": "{id, email, name, plan, admin, via}"}, "401": {"description": "missing or revoked token"}}, "parameters": [], "security": [{"bearer": []}]}}, "/api/v1/recipes": {"get": {"summary": "The recipe catalog, mirrored from github.com/synsema/recipes", "responses": {"200": {"description": "{items: [{slug, name, version, kind, entry, repo, ref, secrets, tagline, tagline_es, tagline_pt}]}"}}, "parameters": []}}, "/api/v1/projects": {"get": {"summary": "Your projects", "responses": {"200": {"description": "{items: [project]}"}, "401": {"description": "missing or revoked token"}}, "parameters": [], "security": [{"bearer": []}]}, "post": {"summary": "Create a project: from files (the package `syn deploy` sends), a recipe, a public GitHub repository, or one pasted entry file", "responses": {"200": {"description": "{project, ceiling, package, missing_secrets}"}, "401": {"description": "missing or revoked token"}}, "parameters": [], "security": [{"bearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string", "description": "string"}, "files": {"type": "string", "description": "[{path, content, encoding: utf8 | base64}] (optional)"}, "recipe": {"type": "string", "description": "slug (optional)"}, "repo": {"type": "string", "description": "https://github.com/owner/repo (optional)"}, "ref": {"type": "string", "description": "branch or tag (optional, with repo)"}, "source": {"type": "string", "description": "string, the entry file (optional)"}, "entry": {"type": "string", "description": "string (optional)"}, "kind": {"type": "string", "description": "web | worker (optional)"}}}}}}}}, "/api/v1/projects/{id}": {"get": {"summary": "One project, its effective ceiling, package, missing secrets and deploys", "responses": {"200": {"description": "{project, ceiling, package, missing_secrets, deploys}"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}]}}, "/api/v1/projects/{id}/package": {"get": {"summary": "The current files of the project", "responses": {"200": {"description": "{entry, kind, package, files: [{path, content, encoding}]}"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}]}}, "/api/v1/projects/{id}/deploys": {"post": {"summary": "Queue a deploy of the current package, or send a new one first", "responses": {"200": {"description": "{deploy, ceiling, missing_secrets, url, logs}"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"files": {"type": "string", "description": "[{path, content, encoding}] (optional, a new package)"}, "entry": {"type": "string", "description": "string (optional, with files)"}, "source": {"type": "string", "description": "string (optional, replaces the entry file)"}}}}}}}}, "/api/v1/projects/{id}/deploys/{did}": {"get": {"summary": "One deploy and the ceiling it was given", "responses": {"200": {"description": "deploy"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}, {"name": "did", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}]}}, "/api/v1/projects/{id}/logs": {"get": {"summary": "Live logs as server-sent events (event: log)", "responses": {"200": {"description": "text/event-stream"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}]}}, "/api/v1/projects/{id}/logs/tail": {"get": {"summary": "Log lines after an id, as JSON (?after=<id>); what `syn logs` polls", "responses": {"200": {"description": "{items: [{id, at, line}], last}"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}]}}, "/api/v1/projects/{id}/audit": {"get": {"summary": "Every capability check, declared versus done (?only=granted|denied)", "responses": {"200": {"description": "{items: [{ts, capability, scope, granted, origin, why}]}"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}]}}, "/api/v1/projects/{id}/secrets": {"get": {"summary": "The secrets set (names and fingerprints, never values) and the ones the manifest still needs", "responses": {"200": {"description": "{items: [{name, fingerprint, created_at}], missing: [name]}"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}]}}, "/api/v1/projects/{id}/secrets/{name}": {"put": {"summary": "Set a secret (UPPER_SNAKE_CASE); the value is never returned", "responses": {"200": {"description": "{ok, name}"}, "401": {"description": "missing or revoked token"}}, "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}, {"name": "name", "in": "path", "required": true, "schema": {"type": "string"}}], "security": [{"bearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"value": {"type": "string", "description": "string"}}}}}}}}}, "components": {"securitySchemes": {"bearer": {"type": "http", "scheme": "bearer"}}}}