{"openapi":"3.1.0","info":{"title":"envpass API","version":"1.0.0","description":"Secrets per project, service and environment. Values are encrypted at rest; every read and write is audited."},"servers":[{"url":"https://envpass.dev"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"A service token (`ep_live_…`) or a CLI session token from the device flow (`POST /api/auth/device/code`)."}},"schemas":{"Workspace":{"type":"object","properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"name":{"type":"string"},"slug":{"type":"string"},"isOwner":{"type":"boolean"}},"required":["id","name","slug","isOwner"]},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","not_found","conflict","invalid","limit_reached","rate_limited"]},"message":{"type":"string"},"limit":{"type":"string"}},"required":["code","message"]}},"required":["error"]},"Ok":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]},"Usage":{"type":"object","properties":{"workspace":{"type":"array","items":{"type":"object","properties":{"limit":{"type":"string"},"label":{"type":"string"},"used":{"type":"number"},"max":{"type":"number"}},"required":["limit","label","used","max"]}},"projects":{"type":"array","items":{"type":"object","properties":{"projectId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"name":{"type":"string"},"keys":{"type":"object","properties":{"used":{"type":"number"},"max":{"type":"number"}},"required":["used","max"]},"services":{"type":"object","properties":{"used":{"type":"number"},"max":{"type":"number"}},"required":["used","max"]}},"required":["projectId","name","keys","services"]}},"rates":{"type":"object","properties":{"apiRequestsPerMinute":{"type":"number"},"resolvesPerMinute":{"type":"number"},"shareLinksPerDay":{"type":"number"},"invitesPerDay":{"type":"number"},"valueBytes":{"type":"number"}},"required":["apiRequestsPerMinute","resolvesPerMinute","shareLinksPerDay","invitesPerDay","valueBytes"]}},"required":["workspace","projects","rates"]},"Environment":{"type":"object","properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"workspaceId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"slug":{"type":"string"},"name":{"type":"string"},"position":{"type":"integer"},"isProduction":{"type":"boolean"},"allowPersonalOverrides":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"}},"required":["id","workspaceId","slug","name","position","isProduction","allowPersonalOverrides","createdAt"]},"Access":{"type":"string","enum":["none","read","write"]},"Role":{"type":"object","properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"name":{"type":"string"},"description":{"type":["string","null"]},"preset":{"type":["string","null"]},"locked":{"type":"boolean"},"manage":{"$ref":"#/components/schemas/ManageFlags"},"access":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Access"}},"memberCount":{"type":"integer"},"projectAssignmentCount":{"type":"integer"},"assignable":{"type":"boolean","description":"Whether you may assign this role to someone"}},"required":["id","name","description","preset","locked","manage","access","memberCount","projectAssignmentCount","assignable"]},"ManageFlags":{"type":"object","properties":{"projects":{"type":"boolean"},"services":{"type":"boolean"},"environments":{"type":"boolean"},"members":{"type":"boolean"},"roles":{"type":"boolean"},"tokens":{"type":"boolean"},"audit":{"type":"boolean"},"shares":{"type":"boolean"}},"required":["projects","services","environments","members","roles","tokens","audit","shares"]},"RoleInput":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":40},"description":{"type":["string","null"],"maxLength":200},"manage":{"$ref":"#/components/schemas/ManageFlags"},"access":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Access"}}},"required":["name","manage","access"]},"Member":{"type":"object","properties":{"userId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"name":{"type":"string"},"email":{"type":"string"},"image":{"type":["string","null"]},"roleId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"roleName":{"type":"string"},"isOwner":{"type":"boolean"},"joinedAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"projectRoles":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"projectId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"projectName":{"type":"string"},"roleId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"roleName":{"type":"string"}},"required":["userId","projectId","projectName","roleId","roleName"]}}},"required":["userId","name","email","image","roleId","roleName","isOwner","joinedAt","projectRoles"]},"Invitation":{"type":"object","properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"email":{"type":"string"},"roleId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"roleName":{"type":"string"},"expiresAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"createdAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"invitedBy":{"type":"string"}},"required":["id","email","roleId","roleName","expiresAt","createdAt","invitedBy"]},"Project":{"type":"object","properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"name":{"type":"string"},"slug":{"type":"string"},"createdAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"serviceCount":{"type":"integer"}},"required":["id","name","slug","createdAt","serviceCount"]},"Service":{"type":"object","properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"projectId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"name":{"type":"string"},"slug":{"type":"string"},"createdAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"}},"required":["id","projectId","name","slug","createdAt"]},"ServiceToken":{"type":"object","properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"name":{"type":"string"},"displayPrefix":{"type":"string"},"access":{"type":"string","enum":["read","write"]},"projectId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"projectName":{"type":"string"},"serviceId":{"type":["string","null"]},"serviceName":{"type":["string","null"]},"createdByUserId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"createdByName":{"type":"string"},"createdByEmail":{"type":"string"},"environments":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","expired","revoked"]},"expiresAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"lastUsedAt":{"type":["string","null"],"format":"date-time","example":"2026-11-12T10:00:00.000Z"},"revokedAt":{"type":["string","null"],"format":"date-time","example":"2026-11-12T10:00:00.000Z"},"createdAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"}},"required":["id","name","displayPrefix","access","projectId","projectName","serviceId","serviceName","createdByUserId","createdByName","createdByEmail","environments","status","expiresAt","lastUsedAt","revokedAt","createdAt"]},"AuditEntry":{"type":"object","properties":{"id":{"type":"integer"},"action":{"type":"string"},"actorType":{"type":"string","enum":["user","token","system"]},"actorUserId":{"type":["string","null"]},"actorTokenId":{"type":["string","null"]},"actorName":{"type":["string","null"]},"actorEmail":{"type":["string","null"]},"projectId":{"type":["string","null"]},"serviceId":{"type":["string","null"]},"environmentId":{"type":["string","null"]},"keyName":{"type":["string","null"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"ip":{"type":["string","null"]},"userAgent":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"}},"required":["id","action","actorType","actorUserId","actorTokenId","actorName","actorEmail","projectId","serviceId","environmentId","keyName","metadata","ip","userAgent","createdAt"]},"Resolved":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"},"source":{"$ref":"#/components/schemas/SecretSource"}},"required":["key","value","source"]}}},"required":["entries"]},"SecretSource":{"type":"string","enum":["shared","service","personal"]},"SecretList":{"type":"object","properties":{"access":{"$ref":"#/components/schemas/Access"},"personalOverridesEnabled":{"type":"boolean"},"entries":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"effective":{"$ref":"#/components/schemas/SecretSource"},"shared":{"type":["object","null"],"properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"updatedAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"updatedBy":{"type":["string","null"]},"note":{"type":["string","null"]}},"required":["id","updatedAt","updatedBy","note"]},"service":{"type":["object","null"],"properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"updatedAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"updatedBy":{"type":["string","null"]},"note":{"type":["string","null"]}},"required":["id","updatedAt","updatedBy","note"]},"personal":{"type":["object","null"],"properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"updatedAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"updatedBy":{"type":["string","null"]},"note":{"type":["string","null"]}},"required":["id","updatedAt","updatedBy","note"]}},"required":["key","effective","shared","service","personal"]}}},"required":["access","personalOverridesEnabled","entries"]},"UpsertResult":{"type":"object","properties":{"created":{"type":"array","items":{"type":"string"}},"updated":{"type":"array","items":{"type":"string"}},"unchanged":{"type":"array","items":{"type":"string"}}},"required":["created","updated","unchanged"]},"UpsertSecrets":{"type":"object","properties":{"environmentId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"serviceId":{"type":["string","null"],"example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"personal":{"type":"boolean"},"entries":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","example":"DATABASE_URL"},"value":{"type":"string"},"note":{"type":["string","null"],"maxLength":200}},"required":["key","value"]},"minItems":1,"maxItems":500}},"required":["environmentId","entries"]},"VersionList":{"type":"object","properties":{"key":{"type":"string"},"currentVersionId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"versions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"createdAt":{"type":"string","format":"date-time","example":"2026-11-12T10:00:00.000Z"},"note":{"type":["string","null"]},"authorName":{"type":["string","null"]},"authorEmail":{"type":["string","null"]},"createdByTokenId":{"type":["string","null"]},"isCurrent":{"type":"boolean"}},"required":["id","createdAt","note","authorName","authorEmail","createdByTokenId","isCurrent"]}}},"required":["key","currentVersionId","versions"]}},"parameters":{}},"paths":{"/api/v1/me":{"get":{"tags":["Workspaces"],"security":[{"bearer":[]}],"summary":"Who am I","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"actor":{"type":"string","enum":["user","token"]},"userId":{"type":"string"},"token":{"type":["object","null"],"properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"projectId":{"type":"string"},"serviceId":{"type":["string","null"]},"access":{"type":"string","enum":["read","write"]}},"required":["id","workspaceId","projectId","serviceId","access"]},"workspaces":{"type":"array","items":{"$ref":"#/components/schemas/Workspace"}}},"required":["actor","userId","token","workspaces"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces":{"get":{"tags":["Workspaces"],"security":[{"bearer":[]}],"summary":"List your workspaces","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workspaces":{"type":"array","items":{"$ref":"#/components/schemas/Workspace"}}},"required":["workspaces"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Workspaces"],"security":[{"bearer":[]}],"summary":"Create a workspace","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":60},"slug":{"type":"string"}},"required":["name"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}":{"get":{"tags":["Workspaces"],"security":[{"bearer":[]}],"summary":"Get a workspace","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"isOwner":{"type":"boolean"},"role":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"required":["id","name","slug","isOwner","role"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Workspaces"],"security":[{"bearer":[]}],"summary":"Rename a workspace","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Workspaces"],"security":[{"bearer":[]}],"summary":"Delete a workspace (owner only)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string"},"required":true,"name":"confirm","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/usage":{"get":{"tags":["Workspaces"],"security":[{"bearer":[]}],"summary":"Usage against limits","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/environments":{"get":{"tags":["Environments"],"security":[{"bearer":[]}],"summary":"List environments","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"environments":{"type":"array","items":{"$ref":"#/components/schemas/Environment"}}},"required":["environments"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Environments"],"security":[{"bearer":[]}],"summary":"Create an environment","description":"Owner and Admin roles always get write. Other roles get none unless copyPermissionsFrom or roleAccess says otherwise.","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":40},"slug":{"type":"string"},"isProduction":{"type":"boolean"},"allowPersonalOverrides":{"type":"boolean"},"copyPermissionsFrom":{"type":["string","null"],"example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"roleAccess":{"type":"array","items":{"type":"object","properties":{"roleId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"access":{"$ref":"#/components/schemas/Access"}},"required":["roleId","access"]}}},"required":["name","slug"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/environments/{environmentId}":{"patch":{"tags":["Environments"],"security":[{"bearer":[]}],"summary":"Update an environment","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"environmentId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"isProduction":{"type":"boolean"},"allowPersonalOverrides":{"type":"boolean"},"position":{"type":"integer"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Environments"],"security":[{"bearer":[]}],"summary":"Delete an environment and every secret in it","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"environmentId","in":"path"},{"schema":{"type":"string"},"required":true,"name":"confirm","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/roles":{"get":{"tags":["Roles"],"security":[{"bearer":[]}],"summary":"List roles with their permission matrix","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"roles":{"type":"array","items":{"$ref":"#/components/schemas/Role"}}},"required":["roles"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Roles"],"security":[{"bearer":[]}],"summary":"Create a custom role","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleInput"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/roles/{roleId}":{"patch":{"tags":["Roles"],"security":[{"bearer":[]}],"summary":"Update a role","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"roleId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Roles"],"security":[{"bearer":[]}],"summary":"Delete an unused custom role","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"roleId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/members":{"get":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"List members","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}},"required":["members"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/members/{userId}":{"patch":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"Change a member's workspace role","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"userId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"roleId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"}},"required":["roleId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"Remove a member (or leave, with your own id)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"userId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"disabledTokens":{"type":"integer"}},"required":["disabledTokens"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/members/{userId}":{"put":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"Set or clear a member's role for one project","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"userId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"roleId":{"type":["string","null"],"example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"}},"required":["roleId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/access":{"get":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"Who can access a project, and pending project invitations","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"canManage":{"type":"boolean"},"people":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"image":{"type":["string","null"]},"roleId":{"type":"string"},"roleName":{"type":"string"},"via":{"type":"string","enum":["owner","workspace","project"]}},"required":["userId","name","email","image","roleId","roleName","via"]}},"pending":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"roleId":{"type":"string"},"roleName":{"type":"string"},"expiresAt":{"type":"string"}},"required":["id","email","roleId","roleName","expiresAt"]}}},"required":["canManage","people","pending"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/share":{"post":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"Share one project with someone by email","description":"Existing workspace members get this role on the project. Anyone else is invited with no default access, plus this role on the project.","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"roleId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"}},"required":["email","roleId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["granted","invited"]},"url":{"type":["string","null"]}},"required":["status","url"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/invitations":{"get":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"List pending invitations","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"invitations":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}}},"required":["invitations"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"Invite someone by email","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"roleId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"projectRoles":{"type":"array","items":{"type":"object","properties":{"projectId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"roleId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"}},"required":["projectId","roleId"]}}},"required":["email","roleId"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"expiresAt":{"type":"string"}},"required":["id","url","expiresAt"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/invitations/{invitationId}":{"delete":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"Revoke an invitation","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"invitationId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/invitations/accept":{"post":{"tags":["Members"],"security":[{"bearer":[]}],"summary":"Accept an invitation","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string"},"workspaceSlug":{"type":"string"}},"required":["workspaceId","workspaceSlug"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects":{"get":{"tags":["Projects"],"security":[{"bearer":[]}],"summary":"List projects you can see","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}},"required":["projects"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Projects"],"security":[{"bearer":[]}],"summary":"Create a project","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"slug":{"type":"string"}},"required":["name"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}":{"get":{"tags":["Projects"],"security":[{"bearer":[]}],"summary":"Get a project","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","name","slug","createdAt"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Projects"],"security":[{"bearer":[]}],"summary":"Rename a project","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Projects"],"security":[{"bearer":[]}],"summary":"Delete a project and all of its secrets","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string"},"required":true,"name":"confirm","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/services":{"get":{"tags":["Services"],"security":[{"bearer":[]}],"summary":"List services","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/Service"}}},"required":["services"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Services"],"security":[{"bearer":[]}],"summary":"Create a service","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":40},"slug":{"type":"string"}},"required":["name"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/services/{serviceId}":{"patch":{"tags":["Services"],"security":[{"bearer":[]}],"summary":"Rename a service","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"serviceId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Services"],"security":[{"bearer":[]}],"summary":"Delete a service and its overrides","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"serviceId","in":"path"},{"schema":{"type":"string"},"required":true,"name":"confirm","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/tokens":{"get":{"tags":["Service tokens"],"security":[{"bearer":[]}],"summary":"List service tokens","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":false,"name":"projectId","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"tokens":{"type":"array","items":{"$ref":"#/components/schemas/ServiceToken"}}},"required":["tokens"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Service tokens"],"security":[{"bearer":[]}],"summary":"Create a service token (the token is only returned once)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"projectId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"serviceId":{"type":["string","null"],"example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"environmentIds":{"type":"array","items":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"minItems":1},"access":{"type":"string","enum":["read","write"]},"ttlDays":{"anyOf":[{"type":"number","enum":[30]},{"type":"number","enum":[90]},{"type":"number","enum":[365]}]}},"required":["name","projectId","environmentIds","access","ttlDays"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"token":{"type":"string"},"displayPrefix":{"type":"string"},"expiresAt":{"type":"string"}},"required":["id","token","displayPrefix","expiresAt"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/tokens/{tokenId}":{"delete":{"tags":["Service tokens"],"security":[{"bearer":[]}],"summary":"Revoke a service token","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"tokenId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/audit":{"get":{"tags":["Audit"],"security":[{"bearer":[]}],"summary":"Read the audit log (newest first)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string"},"required":false,"name":"actorUserId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"projectId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"environmentId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"action","in":"query"},{"schema":{"type":["integer","null"]},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"}},"nextCursor":{"type":["number","null"]}},"required":["entries","nextCursor"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/resolve":{"get":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Resolve the merged values for a service in an environment","description":"Merges Shared, then the service's overrides, then your personal overrides (user tokens only). Service tokens infer workspace and project. `format=dotenv|shell` returns text, ready to write to a file.","parameters":[{"schema":{"type":"string","description":"Workspace slug"},"required":false,"description":"Workspace slug","name":"workspace","in":"query"},{"schema":{"type":"string","description":"Project slug"},"required":false,"description":"Project slug","name":"project","in":"query"},{"schema":{"type":"string","description":"Environment slug","example":"prod"},"required":true,"description":"Environment slug","name":"environment","in":"query"},{"schema":{"type":"string","description":"Service slug, or \"shared\""},"required":false,"description":"Service slug, or \"shared\"","name":"service","in":"query"},{"schema":{"type":"string","enum":["json","dotenv","shell"],"default":"json"},"required":false,"name":"format","in":"query"}],"responses":{"200":{"description":"Resolved values","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resolved"}},"text/plain":{"schema":{"type":"string"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/secrets":{"get":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"List keys (no values) with their inheritance source","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"environmentId","in":"query"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":false,"name":"serviceId","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretList"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Create or update keys in one layer","description":"Omit serviceId to write the Shared layer. Set personal=true to write your own overrides (non-production environments that allow it).","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSecrets"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertResult"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/secrets/{secretId}/reveal":{"post":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Reveal one value (audited)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"secretId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}},"required":["key","value"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/secrets/{secretId}":{"patch":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Rename a key","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"secretId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string"}},"required":["key"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Delete a key (restorable for 30 days)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"secretId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/secrets/{secretId}/restore":{"post":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Restore a deleted key","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"secretId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/secrets/{secretId}/versions":{"get":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Version history (no values)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"secretId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionList"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/secrets/{secretId}/versions/{versionId}/reveal":{"post":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Reveal an old version (audited)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"secretId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"versionId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"value":{"type":"string"}},"required":["value"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/secrets/{secretId}/versions/{versionId}/restore":{"post":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Roll back to an old version (adds a new version)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"secretId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"versionId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/import":{"post":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Import a .env file into one layer","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"environmentId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"serviceId":{"type":["string","null"],"example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"content":{"type":"string","maxLength":524288},"onConflict":{"type":"string","enum":["skip","overwrite"],"default":"skip"},"dryRun":{"type":"boolean","default":false}},"required":["environmentId","content"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"line":{"type":"number"},"message":{"type":"string"}},"required":["line","message"]}},"entries":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"status":{"type":"string","enum":["new","changed","same"]},"bytes":{"type":"number"}},"required":["key","status","bytes"]}},"result":{"allOf":[{"$ref":"#/components/schemas/UpsertResult"},{"type":["object","null"],"properties":{"skipped":{"type":"array","items":{"type":"string"}}},"required":["skipped"]}]}},"required":["errors","entries","result"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/compare":{"get":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Compare one layer across two environments (no values)","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":false,"name":"serviceId","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"status":{"type":"string","enum":["only_from","only_to","same","different"]}},"required":["key","status"]}}},"required":["rows"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspaces/{workspaceId}/projects/{projectId}/promote":{"post":{"tags":["Secrets"],"security":[{"bearer":[]}],"summary":"Copy selected keys from one environment to another","parameters":[{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"workspaceId","in":"path"},{"schema":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"required":true,"name":"projectId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"to":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"serviceId":{"type":["string","null"],"example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"keys":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":500}},"required":["from","to","keys"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertResult"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/shares":{"post":{"tags":["Share links"],"security":[{"bearer":[]}],"summary":"Store an encrypted share link","description":"Encrypt in the client with AES-256-GCM and keep the key in the URL fragment. The server only stores ciphertext.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ciphertext":{"type":"string","minLength":1},"iv":{"type":"string","minLength":1},"passphraseSalt":{"type":["string","null"]},"ttl":{"type":"string","enum":["1h","1d","7d"],"default":"1d"},"maxViews":{"type":"integer","minimum":1,"maximum":10,"default":1},"source":{"type":["object","null"],"properties":{"workspaceId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"projectId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"environmentId":{"type":"string","example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"serviceId":{"type":["string","null"],"example":"0193b3c2-6a8e-7c1f-9b0e-2f9d2a4c1e77"},"keys":{"type":"array","items":{"type":"string"},"maxItems":500}},"required":["workspaceId","projectId","environmentId","keys"]}},"required":["ciphertext","iv"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"expiresAt":{"type":"string"}},"required":["id","expiresAt"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/shares/{shareId}":{"get":{"tags":["Share links"],"summary":"Check a share link without using up a view","parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9]{22}$"},"required":true,"name":"shareId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"expiresAt":{"type":"string"},"viewsLeft":{"type":"number"},"hasPassphrase":{"type":"boolean"}},"required":["expiresAt","viewsLeft","hasPassphrase"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/shares/{shareId}/open":{"post":{"tags":["Share links"],"summary":"Open a share link (uses one view, deletes it after the last)","parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9]{22}$"},"required":true,"name":"shareId","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ciphertext":{"type":"string"},"iv":{"type":"string"},"passphraseSalt":{"type":["string","null"]},"viewsLeft":{"type":"number"}},"required":["ciphertext","iv","passphraseSalt","viewsLeft"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed, or a limit was reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{}}