Calling the PivoCloud API with a personal access token
The API lets a script do one thing today: start an export of one of your own databases, and download the result. This page covers that in three parts, in the order you meet them. Creating a token in the console. Sending a request with it and reading what comes back. And what to do when the API answers that you should wait rather than starting an export.Create the token
A personal access token is created in the console, and it is the only credential the API accepts. Every token is fixed to one thing, pulling backups of your own databases, so there is no scope to choose and no permission to set.- Open your profile in the console and find the
API Tokenssection. - Press
Create token. A dialog opens, titledCreate API token. - Type a name into
Token name. The name is the only thing the dialog asks for, and it is there so that you can recognise this token later in the list. - Press
Create tokenin the dialog.
Revoke button on every row.
Revoking takes effect at once, so anything still calling the API with that
token starts failing straight away.
Call the API
One request starts an export. It is aPOST to the export path for the
database you want, and it carries your token as a bearer credential in the
request’s authorization header:
200, and its body carries two fields:
url is the link your export will be served from. expires_at is the moment
that link stops working, so a script that stores the link is better off storing
that with it. Both are absolute values the server has already assembled, so there
is nothing on your side to build and nothing to guess at.
The expiry in that example is a placeholder like the other values in it, and it
is not a typical one. A real link is short-lived, minutes rather than days, so
read the moment out of expires_at rather than budgeting from what is printed
above. A link asked for after that moment answers 401 instead of serving the
archive, which is the link having expired rather than anything wrong with your
request. Mint the link close to when you will use it, and start a new export if
the one you have has lapsed.
The link carries its own authorisation. The signature inside it is what grants
access, so downloading needs no token and no header at all: a plain GET on
that address is the whole download. Treat the link exactly as you treat the
token, because anyone holding it can fetch that dump until it expires. It is
not a public address that merely happens to be long.
The export itself starts after this request returns, so the link is not ready
at the moment you receive it. It answers 503 while the archive is still being
prepared, then serves the archive once it is finished. A script can therefore
ask for an export and poll that one link until it succeeds, without asking for
a status anywhere else.
Poll on a wait and stop on anything else. 503 is a wait, and so is 429;
both carry the interval to sleep for in their Retry-After header. Every other
reply is the end of that loop rather than a step in it. An export that failed
is the one to plan for: the link answers 404 from then on and keeps answering
404 however long you keep asking, so a loop that reads it as “not ready yet”
runs forever. Treat anything that is not a wait as the export not coming, and
start a new one. The full list of replies each endpoint can send is in the
generated reference rather than on this page, so there is one copy of it and it
comes from the same document the API itself is described by.
When the API tells you to wait
Two of the export endpoint’s answers are a refusal to start a new export right now rather than a failure, and both arrive as429. From the status code alone
they are indistinguishable, and a script that treats them as the same thing
sits out a whole cooldown window for a wait that should have been seconds. Read the code in the body to tell them
apart, and read the wait from the Retry-After header of the reply rather than
from a figure written down anywhere. That header carries the number of seconds
to wait, the server sets it per reply, and it is the only value that is true at
the moment you receive it. This page deliberately prints no figure: the
cooldown window is read from configuration when the API starts, so a number
published here would quietly stop being true. A code you do not recognise is
safest treated as a wait as well: ask again after the interval the header
names, rather than stopping the job outright.
cooldown_active means this database was exported recently. The wait is the
whole cooldown window and there is nothing to poll, because your request
started no export. This is the one to sleep through.
export_in_flight means an export for this database is already running. The
wait is short, seconds rather than a cooldown window, and sleeping through a
full cooldown here is the mistake this section exists to prevent. The better
move is not to ask again at all. The request that started that export already
returned a link, and that link resolves to the archive once the export
finishes, so poll the link you were given.
A third code also arrives as 429 and it is not about your database at all.
RATE_LIMIT_EXCEEDED is the limit on how often you may call the API, it
applies to every endpoint here rather than to one database, and the same rule
covers it: read the wait from Retry-After and ask again.