@pierre/sdk for TypeScript and JavaScript,
pierre-sdk for Python, and github.com/pierrecomputer/sdk/go for Go. This page explains what
applies to every call. The reference page of each operation shows the call of that operation in each
language.
The earlier Code Storage SDKs,
@pierre/storage, pierre-storage, and code-storage-go, have
their own docs: Storage SDK. To move code to this SDK, use the pierre-migrate
skill.Install
import and top-level await. In a Node.js project, set
"type": "module" in your package.json, or use .mts files:
package.json
Create a client
PIERRE_TOKEN first, then PIERRE_PRIVATE_KEY, then
PIERRE_PRIVATE_KEY_FILE. With no credential, or no organization for the default hosts, the client
raises PierreError, or pierre.NewClient returns an error.
The Settings page of your organization in the dashboard shows your API host and Git host. Set
PIERRE_API_BASE_URL to the API origin and PIERRE_GIT_HOST to the Git host of remote URLs only
when they are not the defaults. Give the API origin with no path. The client adds the path of each
operation, which starts with /api.
TypeScript and Python read PIERRE_PRIVATE_KEY_FILE when they sign the first token. TypeScript
needs node:fs for it. Go reads the key at once, also from the file, and returns an error for a key
that it cannot read.
Explicit options
An option replaces its variable. A credential in the options replaces every credential in the environment. The comments name the variable of each option.PIERRE_PRIVATE_KEY_FILE has no option.
getToken in
TypeScript, get_token in Python, and option.WithGetToken in Go. The client calls it for each
request, with the scopes, the repo claim, the lifetime, and the ref policies of that request. Your
server signs the token, for example with the token helper.
- Python: an argument that is
Nonefalls back to its variable, then to the default. - Go: the function of
option.WithGetTokengets the context of the attempt and anoption.TokenRequest.
Call an operation
The method path is the catalog ID of the operation. The params and the results use the wire names of the HTTP API, such asrepo_name and target_branch.
- TypeScript:
repos.branches.createispierre.repos.branches.create(). Each method takes one params object, and the request options as its second argument. - Python: each segment is in snake_case, so
repos.gitCredentials.createispierre.repos.git_credentials.create(). Each method takes keyword arguments. An optional argument has the defaultNOT_GIVEN, and the client does not send it.Nonesendsnullin a body field, and raisesPierreErrorin a query or header argument. - Go: the path is in Go names,
client.Repos.Branches.Create, with the params structpierre.ReposBranchesCreateParams. Each method takes acontext.Context, the params, and request options. The JSON tags are the wire names. A required field has its plain type, and an optional field is apierre.Opt[T]. A params struct has no deprecated field of the API. A nested request type, such aspierre.BaseRepo, and a response type keep their deprecated fields, each with aDeprecated:comment.
repos.branches.create.
Options
Client options
fetch in TypeScript, an httpx.Client in Python, and an
*http.Client in Go. The timeout applies to each attempt. The headers can replace the
Pierre-Client header, for example pierre-sdk-typescript/<version>.
The options of a client hold its settings, with no credential: pierre.options in TypeScript and
Python, and client.Options() in Go. withOptions (with_options in Python, WithOptions in Go)
returns a copy of the client with changed options. The copy keeps the credential and each option
that you do not change. Ref policies shows an example.
- Python: a client keeps one httpx client.
with Pierre() as pierre:closes the httpx client that the SDK made at the end of the block. Anhttp_clientthat you give stays open. For a client that lives as long as the process, create it one time. - Go: one
option.RequestOptionserves a client and one request, and an option for the wrong use returns an error. Inclient.WithOptions,option.WithHeaderadds a header to the default headers.
Request options
A request option holds a setting for one call, and replaces the client option for that call. It goes in the second argument in TypeScript, in the keyword arguments in Python, and in the last arguments in Go.- To stop a call, use the
signalin TypeScript, cancel theasynciotask in Python, or cancel thecontext.Contextin Go. - Response headers shows the response option:
withResponse()in TypeScript,pierre.with_raw_responsein Python, andoption.WithResponseIntoin Go.
Ref policies
The ref policies limit the refs that a write can change. The client puts the rules in therefs
claim of each request token. The first rule whose pattern matches a ref applies.
- A pattern is a full ref name (
refs/heads/main), a branch name (main), a prefix that ends with/*, or*. The ops areno-push,no-force-push, andverify-sig. - A request option replaces the rules of the client for that call. An empty list removes them:
[], oroption.WithRefPolicies()with no rule. - The token function receives the rules.
- A client with a fixed token cannot use ref policies, because the client cannot change the claims of that token.
- The token and remote URL helpers use the rules of the client when the call gives none, so a confined client stays confined through Git.
Responses
A call gives one of three kinds of result: a JSON body, no body, or bytes.repos.files.metadata.get has no body, and
repos.files.get and repos.archive.get give bytes. In TypeScript, each method returns an
APIPromise, and the request starts when you call the method.
Response headers
The response of a call gives its headers and its request ID.- TypeScript and Python:
datais the result of the call, andresponseis the response of the last attempt.headersholds the response headers that the reference page declares, with the wire form of each name, such asx_cache,etag, andx_blob_sha.request_idis theX-Request-Idheader, or none. In a browser, the client can read only the headers that the API exposes through CORS. - Go:
option.WithResponseIntostores the*http.Responseof the last attempt, with every header.
Byte responses
A byte response returns when its headers arrive. You read the body, so the timeout ends with the headers, and the client does not retry the body. In Python and Go, close the stream when you are done, as Responses shows. In TypeScript,asResponse() gives the platform Response of a JSON operation when its headers
arrive, and does not read the body. Use it to read a large body yourself. After await or
withResponse(), the client has already read the body.
TypeScript
Lists and pagination
A list method returns the first page. A loop on the result gives the items of every page:data, with has_more, next_cursor, body, and response (Data,
HasMore, NextCursor, Body, and Response in Go). body is the full response body, with the
fields beside the items. The page iterator gives this page, then each next page:
hasNextPage(), then get it with
getNextPage(): has_next_page() and get_next_page() in Python, HasNextPage() and
GetNextPage(ctx) in Go. The next page sends the params and the request options of the first call.
To store a page, serialize its body, the response that the API sent. JSON.stringify(page) and
json.Marshal(page) give the body. In TypeScript, withResponse() and asResponse() on a list
give the response of the first page.
Errors
Every error of the SDK extendsPierreError. Import the classes from @pierre/sdk or pierre. In
Go, each error is a pointer type, such as *pierre.NotFoundError, that unwraps to a
*pierre.PierreError, and you branch with errors.As.
APIError: the API sent an error response. It hasstatus,code,title,detail,request_id,headers,body, anddoc_url.- The
APIErrorof each status family. Another status, such as 412, gives a plainAPIError.BadRequestError: 400AuthenticationError: 401PermissionDeniedError: 403NotFoundError: 404ConflictError: 409RateLimitError: 429InternalServerError: 5xx
MergeConflictError: aConflictErrorfor a merge conflict, withconflict_type,conflict_paths, andmerge_base_sha.RefGuardError: aConflictErrorwith the coderef_guard_failed, withguardandcurrent_sha.RefUpdateError: anAPIErrorfor a Git write whose ref update failed, withresultandcommit.APIConnectionError: the request got no response.APITimeoutError: anAPIConnectionError. The attempt got no response before its timeout.WebhookVerificationError: the webhook helper rejected a delivery.reasonsays why.
code, not on the message. Error codes
lists the codes.
- A failed ref guard raises
RefGuardError.guardnames the request field of the guard, for exampleexpected_target_sha.current_shais the current commit of the ref. Send it as the guard of the next attempt. - Another failed ref update raises
RefUpdateError. Itsresulthasstatus, which gives the reason, for exampleconflict, with no cast.resultis aRefUpdateResult, or aNotesWriteResultfor a notes write. In Go,Resultis always aRefUpdateResult, and a notes write fills onlySuccess,Status, andMessage.codecan be empty on aRefUpdateError. - A
NotFoundErrorhas the coderepository_not_foundwhen the repository does not exist. A missing object in the repository, such as a file or a note, has the codenot_found. - Go: check
*pierre.RefGuardErrorbefore*pierre.ConflictError, because it unwraps to one. A*pierre.RefUpdateErrorunwraps to the*pierre.APIError, not to a*pierre.ConflictError. The end of the context of a call returns the cause of the context, and an error of your own function, such asOpenof apierre.CommitFile, reaches you as it is.
Retries and timeouts
The client retries a connection error, a timeout, 408, 429, 5xx, and 409 with the coderepository_thawing or sync_in_progress. It retries only GET, HEAD, PUT, and DELETE
requests, so a write such as repos.commits.create never retries. It waits for Retry-After when
the value is 60 seconds or less. Else it backs off from 0.5 seconds, up to 8 seconds.
Each attempt has its own timeout: 60 seconds by default. The timeout covers the token, the upload,
the response headers, and a JSON body. Give a larger timeout for a large commit. When the last
attempt times out, the call raises APITimeoutError.
A retried DELETE can get a 404 when the first attempt worked and its response was lost. To turn
off the retries of a call, set its retries to 0: maxRetries: 0, max_retries=0, or
option.WithMaxRetries(0). In Python, Pierre cannot stop a blocking get_token, so the attempt
fails when the token arrives after the deadline.
Python async code
AsyncPierre takes the same arguments as Pierre, and each method is async. Its get_token can be
async, and its http_client is an httpx.AsyncClient.
Python
- A method starts its request when you await it, as a coroutine does.
- A list method returns an
AsyncPaginator.awaitgives the firstAsyncPage, andasync forgives the items of every page.get_next_page()anditer_pages()of anAsyncPageare async. async withcloses the httpx client that the SDK made.- To stop a call, cancel its task.
- With
AsyncPierre, await the result ofremote_url.create_tokenstays synchronous.
Go optional fields
An optional field, or a field that can be null, is apierre.Opt[T]:
- The zero value is omitted. The request does not send it, so the server keeps the stored value.
pierre.String,pierre.Int(anint64),pierre.Float,pierre.Bool, andpierre.Valuegive a value.pierre.Valuetakes any type, such as a struct.pierre.Null[T]()givesnull, which resets the stored value.
Go
Opt too. Get gives the value and whether
the response has one, and IsNull reports null.
An enum is a string type with a constant for each known value, such as
pierre.RefUpdateResultStatusConflict. A response can hold a value that this SDK version does not
list, so give each switch on an enum a default case. In every language, an enum is open.
Go contexts
Each method takes acontext.Context as its first argument. The context stops the call at any time,
also during the wait between two attempts. The call then returns the cause of the context.
option.WithTimeout limits each attempt, and a context limits the whole call, with its retries.
Go
Local helpers
These helpers make no call to the API:- TypeScript: no subpath loads another, so a browser or edge bundle holds only what it imports.
@pierre/sdk/coreexportsPierreCore, the client with no namespaces, and@pierre/sdk/reposexportsReposNamespace, built withnew ReposNamespace(new PierreCore()). - Python:
import pierredoes not load these modules, and a variable namedpierrehides the module. Import them withfrom pierre.<module> import ....
Tokens
The token helper signs a token with the private key of a client, or with an organization and a private key. A client with a fixed token or a token function cannot sign.scopesnames at least one scope.SCOPES(auth.Scopesin Go) lists the scopes of the API.reposets therepoclaim. Leave it out for a token whose scopes are all organization-wide.ttlis the lifetime, from 1 second to 1 hour. Default: 15 minutes.ref_policiessets therefsclaim. Default: the ref policies of the client.
Git remote URLs
The remote URL helper buildshttps://t:<token>@{gitHost}/{repo_name}.git for git clone,
git fetch, and git push.
- The token has
git:readandgit:write, and lives 15 minutes. The scopes and the TTL change them, up to 1 hour. - The kind
ephemeralgives the+ephemeralremote, and the kindimportgives the+importremote:kind: 'ephemeral',kind="ephemeral", orKind: git.KindEphemeral. - It works with a private key or a token function. A client with a fixed token cannot set the claims
of its token, so the helper raises
PierreError.
.git/config, so keep the lifetime short. For longer
work, use the credential helper of the CLI, pierre auth setup-git. See
Git Operations, Ephemeral Branches, and
Imports.
Webhooks
The webhook helper checks theX-Pierre-Signature header of a delivery and returns the typed event.
It raises WebhookVerificationError when the check fails.
- The payload is the raw request body. Do not pass parsed JSON.
- The headers are the request headers: a Fetch
Headersor a record in TypeScript, a mapping in Python, and anhttp.Headerin Go. - The tolerance is the largest age of a delivery. Default: 5 minutes.
- An event type that this SDK version does not know gives an unknown event, with the type that
Pierre sent and the parsed payload:
type: 'unknown'withevent_typeandbodyin TypeScript and Python, and a*webhooks.UnknownEventwithTypeandBodyin Go.
Related pages
- CLI: the
pierrecommand and the Git credential helper. - Authentication: keys, scopes, and token claims.
- Access & Permissions: repository claims and scopes for each client.
- Git Operations: Git over HTTPS with a token.
- Ref Policies: limits on the refs that a token can change.
- Webhooks: events, payloads, and signatures.
- API Overview: HTTP conventions, pagination, and error codes.