Using the API
Authentication
The session cookie the API authenticates with, and why there are no API keys yet.
Updated
The API has one way in: the session cookie the console sets when a customer signs in. There are no API keys, personal tokens or OAuth clients for the API yet.
The session cookie
Signing in to the console with GitHub or Google ends with Cloud setting this cookie on its own address:
| Property | Value |
|---|---|
| Name | cahaves.cloud.session |
| Lifetime | 30 days from sign-in |
| Readable by scripts | No, it is HttpOnly |
| Sent cross-site | Only on top-level navigation, as SameSite=Lax |
| Sent over | HTTPS only |
The session is stored on Cloud's side and can be revoked there, so signing out ends it for every request at once. A request without a valid session answers:
{ "error": "Sign in to continue." }An account Cahaves has banned gets the same 401 on every request, whatever session it holds, and cannot sign in again.
The organization a request works in
The session names a person, and a person can own several organizations. Every customer request works in one of them, which it names in a header:
X-Cloud-Organization: 2f6c8e0a-4b1d-4e7f-9a3c-5d7e9f1b3a5c| Header | The request works in |
|---|---|
| Left out, or empty | Your oldest organization |
| The id of one of your organizations | That organization |
| Any other value, an id that is not yours included | Nothing: it answers 404 with reason: "organization" |
{ "error": "That organization does not exist.", "reason": "organization" }The reason tells this 404 from a record that does not exist. The console sends the header on every request, naming the organization its switcher shows, and on this 404 it drops its choice and asks again without the header.
Projects and everything in them, and billing, are the organization's: a record of another of your organizations answers 404 as one that does not exist would. SSH keys, git providers, notification channels and backup destinations are yours, and answer the same whichever organization the header names. Get the signed-in customer lists your organizations and names the one the request works in.
A new account has no organization until Create an organization makes one. Until then, every route that works in an organization answers:
{ "error": "Create an organization first." }Without an organization, /api/me, the organization routes, the catalogue of databases, applications and instance sizes, SSH keys, git providers, notification channels and deliveries, and support still answer.
What this means for these pages
Scripts cannot read the cookie, and a request sent from another site does not carry it. That rules out calling the API from a server, a CI job or the Try it panel on these pages, which answers 401 for every endpoint until Cloud offers tokens.
The reference is still the exact contract the console is built on: every field, envelope and error below is what the console sends and receives.
Signing in and out
Signing in is a browser navigation, not an API call. These routes sit on the same host as the API, outside /api:
| Route | What it does |
|---|---|
GET /auth/start?provider=github or provider=google | Sends the browser through Cahaves' sign-in service to that provider, then back to the console signed in. The first sign-in creates the account. |
GET /auth/sso | Where the Cahaves account screen opens Cloud. It signs in from the account's existing Cahaves session without showing a screen. |
GET /auth/callback | Where the sign-in service returns the browser. Nothing calls it directly. At most 20 callbacks a minute are accepted from one address; past that it answers 429 with { "error": "Too many attempts." }. |
POST /auth/logout | Ends Cloud's session and clears the cookie. It always answers 204, signed in or not. The Cahaves account session at the sign-in service stays open. |
A sign-in that fails lands on the console's login screen with a code in ?error=, never with text taken from the address. The screen shows one sentence per code:
| Code | Sentence on the login screen |
|---|---|
failed | That sign-in could not be completed. Start again. |
provider | Choose GitHub or Google to sign in. |
unavailable | Sign-in is unavailable right now. Try again in a minute. |
invalid_state | That sign-in expired before it finished. Start again. |
provider_disabled | That sign-in option is not available right now. |
provider_unavailable | The provider did not finish the sign-in. If you did not cancel it, try again in a minute. |
email_not_verified | The provider has not verified your email address. Verify it there, then start again. |
missing_email | The provider did not share an email address, and your account needs one. |
email_taken | An account already uses that email address. Sign in the way you did before, or connect this provider from your Cahaves account screen first. |
account_not_active | That account cannot sign in. |
registration_closed | Cahaves is not taking new accounts right now. |
login_required | Your Cahaves session has ended. Continue with GitHub or Google to sign in again. |
Any other code reads as failed, and so does a banned account. Sign-in problems explains what to do about each.
Two kinds of session
Cahaves staff sign in through a separate route and receive a different cookie. A staff session is never honoured on a customer endpoint, and a customer session never on a staff one, whichever cookie a request carries.
The sockets
The log and terminal sockets use the same cookie. They also refuse any request whose Origin is not the console's own address. They take no organization: a socket reaches a service in any of your organizations. Log and terminal sockets has the details.