{"openapi":"3.1.0","info":{"title":"Rivervo API","version":"1.0.0","description":"Manage your Rivervo Applications from scripts, CI and the `rivervo` CLI.\n\nAuthenticate with a personal API token from Account settings \u2192 API tokens: `Authorization: Bearer <token>`. A token is read, deploy or full; it acts with your own access, and in an account you are a team member of (header `X-Account`) with your role there.\n\nResponses are JSON. Errors carry `message` (in the language of the `Locale` or `Accept-Language` header: en, az, ru) and, for invalid input, `errors`. Rate limits: 120 requests a minute, of them 30 changes; past them 429 with `Retry-After`."},"servers":[{"url":"https://api.rivervo.com/api/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Apps"},{"name":"Deployments"},{"name":"Logs"},{"name":"Variables"},{"name":"Domains"}],"paths":{"/apps":{"get":{"tags":["Apps"],"operationId":"listApps","summary":"List your apps with their services","description":"Token scope: **read**.","x-token-scope":"read","parameters":[{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The apps","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/App"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}":{"get":{"tags":["Apps"],"operationId":"getApp","summary":"An app: status, health, services, the latest deployment, domains","description":"Token scope: **read**.","x-token-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The app","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/AppDetail"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}/restart":{"post":{"tags":["Apps"],"operationId":"restartApp","summary":"Restart the running app","description":"Token scope: **deploy**.","x-token-scope":"deploy","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Restarted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}/deployments":{"get":{"tags":["Deployments"],"operationId":"listDeployments","summary":"Deployments, newest first","description":"Token scope: **read**.","x-token-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Deployments","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DeploymentListItem"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}},"post":{"tags":["Deployments"],"operationId":"deploy","summary":"Deploy: build the latest commit of the branch (rebuild, the default) or deploy the running version again (rebuild: false \u2014 applies changed variables)","description":"Token scope: **deploy**.","x-token-scope":"deploy","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rebuild":{"type":"boolean","default":true}}}}}},"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Deployment"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}/deployments/{deployment}":{"get":{"tags":["Deployments"],"operationId":"getDeployment","summary":"A deployment with its build log","description":"Token scope: **read**.","x-token-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"deployment","in":"path","required":true,"schema":{"type":"integer"}},{"name":"log_offset","in":"query","description":"Return the log from this character on (to follow a running deployment).","schema":{"type":"integer","minimum":0,"default":0}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The deployment","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/DeploymentWithLog"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}/deployments/{deployment}/rollback":{"post":{"tags":["Deployments"],"operationId":"rollback","summary":"Go back to the version of an earlier successful deployment (the last 5 are kept)","description":"Token scope: **deploy**.","x-token-scope":"deploy","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"deployment","in":"path","required":true,"schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Deployment"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}/logs":{"get":{"tags":["Logs"],"operationId":"getLogs","summary":"The end of the app's own output (runtime logs)","description":"Token scope: **read**.","x-token-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"lines","in":"query","schema":{"type":"integer","minimum":1,"maximum":2000,"default":200}},{"name":"process","in":"query","description":"web (default), cron, or a worker: w1, w2\u2026","schema":{"type":"string","pattern":"^(web|cron|w\\d{1,2})$","default":"web"}},{"name":"since","in":"query","description":"Only lines stamped after this time (the `at` of the previous answer) \u2014 to follow the log.","schema":{"type":"string","format":"date-time"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Log lines, each starting with its time","content":{"application/json":{"schema":{"type":"object","required":["data","at"],"properties":{"data":{"type":"object","properties":{"lines":{"type":"array","items":{"type":"string"}},"process":{"type":"string"},"running":{"type":"boolean"}}},"at":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}/env":{"get":{"tags":["Variables"],"operationId":"listVariables","summary":"The app's variables (with their values)","description":"Token scope: **full**.","x-token-scope":"full","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Variables","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Variable"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}},"put":{"tags":["Variables"],"operationId":"replaceVariables","summary":"Replace every variable (they reach the app with its next deployment)","description":"Token scope: **full**.","x-token-scope":"full","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["vars"],"properties":{"vars":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/Variable"}}}}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariablesSaved"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}},"patch":{"tags":["Variables"],"operationId":"updateVariables","summary":"Set some variables and remove others; the rest stay (they reach the app with its next deployment)","description":"Token scope: **full**.","x-token-scope":"full","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"set":{"type":"object","additionalProperties":{"type":"string","maxLength":8192}},"unset":{"type":"array","items":{"type":"string"}},"target":{"type":"string","enum":["all","production","preview"],"description":"Where the variables in `set` go (an app with previews). Default: where they went before, else all."}}}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariablesSaved"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}/domains":{"get":{"tags":["Domains"],"operationId":"listDomains","summary":"The app's own domains","description":"Token scope: **read**.","x-token-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Domains","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}},"post":{"tags":["Domains"],"operationId":"addDomain","summary":"Connect a domain (then point its DNS as the panel shows)","description":"Token scope: **full**.","x-token-scope":"full","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":253,"examples":["shop.example.com"]}}}}}},"responses":{"201":{"description":"Added","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}},"/apps/{id}/domains/{name}":{"delete":{"tags":["Domains"],"operationId":"removeDomain","summary":"Disconnect a domain","description":"Token scope: **full**.","x-token-scope":"full","parameters":[{"name":"id","in":"path","required":true,"description":"The app (or a service of a project \u2014 it has an id of its own).","schema":{"type":"integer"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9.-]+$"}},{"name":"X-Account","in":"header","required":false,"description":"Work in another account you are a team member of (its owner's customer ID). Your role there applies, as in the panel.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"422":{"$ref":"#/components/responses/Invalid"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A personal API token (Account settings \u2192 API tokens)."}},"responses":{"Unauthenticated":{"description":"No token, or it was revoked or has expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The token's scope (reason token_scope) or your team role (reason forbidden / project) does not allow this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"No such app or deployment in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Invalid":{"description":"Invalid input, or the app cannot do this now (message says why)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"TooManyRequests":{"description":"Rate limit reached; see Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["message"],"properties":{"message":{"type":"string"},"reason":{"type":"string"},"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"Status":{"type":"string","enum":["draft","checking","ready","deploying","live","failed","suspended","deleted"]},"App":{"type":"object","required":["id","name","status"],"properties":{"id":{"type":"integer"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string","enum":["web","worker","cron","postgres","mysql","redis"]},"url":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/Status"},"health":{"type":["string","null"],"enum":["up","down",null]},"repo":{"type":["string","null"]},"branch":{"type":["string","null"]},"framework":{"type":["string","null"]},"project_key":{"type":"string"},"resources":{"type":"object","properties":{"memory_mb":{"type":"integer"},"cpus":{"type":"number"},"disk_gb":{"type":"integer"}}},"auto_deploy":{"type":"boolean"},"last_deployed_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":["string","null"],"format":"date-time"},"services":{"type":"array","items":{"$ref":"#/components/schemas/Service"}}}},"AppDetail":{"allOf":[{"$ref":"#/components/schemas/App"},{"type":"object","properties":{"service_of":{"type":["integer","null"],"description":"A service: the id of its project's main app."},"parent_id":{"type":["integer","null"],"description":"A preview: the id of its app."},"latest_deployment":{"oneOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"null"}]},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}}}}]},"Service":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"type":{"type":"string"},"status":{"$ref":"#/components/schemas/Status"},"health":{"type":["string","null"]},"url":{"type":["string","null"]}}},"Deployment":{"type":"object","required":["id","status"],"properties":{"id":{"type":"integer"},"kind":{"type":"string","enum":["release","deploy","move"]},"status":{"type":"string","enum":["queued","running","succeeded","failed"]},"progress":{"type":"integer","minimum":0,"maximum":100},"trigger":{"type":["string","null"]},"steps":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"status":{"type":"string","enum":["pending","running","done","failed"]},"started_at":{"type":"string"},"finished_at":{"type":"string"}}}},"error":{"type":["string","null"]},"commit":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"author":{"type":"string"},"date":{"type":"string"},"message":{"type":"string"}}},{"type":"null"}]},"created_at":{"type":["string","null"],"format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}}},"DeploymentListItem":{"allOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"object","properties":{"current":{"type":"boolean","description":"The version running now."},"can_rollback":{"type":"boolean"}}}]},"DeploymentWithLog":{"allOf":[{"$ref":"#/components/schemas/Deployment"},{"type":"object","properties":{"log":{"type":"string"},"log_offset":{"type":"integer"},"log_length":{"type":"integer"}}}]},"Variable":{"type":"object","required":["key"],"properties":{"key":{"type":"string","pattern":"^[A-Za-z_][A-Za-z0-9_]*$","maxLength":100},"value":{"type":"string","maxLength":8192},"target":{"type":"string","enum":["all","production","preview"],"description":"An app with previews: where the variable goes."}}},"VariablesSaved":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Variable"}},"applies":{"type":"string","enum":["next_deployment"],"description":"Deploy (rebuild: false is enough) to apply them."}}},"Domain":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["pending","active"]},"redirect":{"type":["string","null"]},"added_at":{"type":["string","null"]},"verified_at":{"type":["string","null"]}}}}}}