Account API
The account API manages your algal.cloud account: API keys, habitats, credits and usage. This page is generated from the API contract each time the site is built.
Early access (test mode). Payments run in Stripe test mode and no card is charged. Accounts, limits and prices may change before launch.
Paid endpoints
A paid endpoint is published at api.algal.cloud/e/<org>/<project>, and its public page lives at /e/<org>/<project> on this site. Callers POST a JSON body; the 402 response carries a Stripe test-mode checkout link for an invocation ticket, and the paid ticket goes in the x-algal-ticket header. Each ticket covers a pack of invocations at the price the owner set. A caller with an account key (Authorization: Bearer $ALGAL_KEY, billing scope) is charged from their balance instead, and the 202 response includes the ticket for the rest of the pack. Owners manage endpoints, earnings and payouts with the routes below or the CLI.
Answer calls with a program
Bind a program to an endpoint and each paid call runs it once. Upload the program's bundle to the habitat, then store the binding in the habitat slot endpoint-program.<mailbox>, using the mailbox name the endpoint was created with:
curl -X PUT "$ALGAL_API/v1/habitats/$HABITAT/slots/endpoint-program.answers" \
-H "Authorization: Bearer $ALGAL_KEY" -H "Content-Type: application/json" \
-d '{"value":{"manifest":"sha256:<program digest>"}}'The caller's JSON input arrives on the program's input cell, and the program's value output comes back as {"value": ...}. A run that fails returns {"error": {"code", "message"}} instead. Name a deployment in place of manifest to follow the program as it evolves, and add an executor for programs that call a model. Without a binding, calls wait in the mailbox for a process you run yourself.
Routes
Send the key as Authorization: Bearer $ALGAL_KEY. Generated from packages/protocol/src/account-api.ts (sha256 a709fb7e3a47).
| Method | Path | What it does |
|---|---|---|
GET | /v1/account | |
POST | /v1/account/tenant | (header Idempotency-Key) → 201 |
GET | /v1/account/keys | |
POST | /v1/account/keys | → 201. The plaintext key appears only here, once. |
POST | /v1/account/keys/:keyId/revoke | → 200 |
GET | /v1/account/habitats | |
POST | /v1/account/credits/checkout | |
GET | /v1/account/usage | |
GET | /v1/account/org | the account's org slug, or `org: null`. |
POST | /v1/account/org; | PATCH /v1/account/org (rename while unbound). |
GET | /v1/account/endpoints | item. |
POST | /v1/account/endpoints | → 201. |
PATCH | /v1/account/endpoints/:project | omitted fields are unchanged. |
GET | /v1/account/earnings | the owner's journaled ledger view (W3-PAY). |
POST | /v1/account/earnings/apply | move available earnings into the |
POST | /v1/account/payouts/link | Connect Express onboarding URL for the |
POST | /v1/account/payouts | transfer available earnings to the bound |
POST | /v1/account/task-campaigns | |
POST | /v1/account/org | |
PATCH | /v1/account/org |
Error codes
Errors come back as {"error":{"code","message"}}. The codes are:
UNAUTHORIZEDNOT_ADMITTEDEMAIL_UNVERIFIEDRATE_LIMITEDTENANT_CAP_REACHEDTENANT_EXISTSACCOUNT_API_DISABLEDUNAVAILABLEPARSE_FAILEDCONFLICTNOT_FOUNDACCOUNT_CREATE_FAILEDACCOUNT_PENDING
Types
AccountErrorCode
export type AccountErrorCode = typeof ACCOUNT_ERROR_CODES[number];AccountApiErrorBody
export type AccountApiErrorBody = {
error: {
code: AccountErrorCode;
message: string;
};
};AccountAdmission
--- shapes -------------------------------------------------------------
export type AccountAdmission = "admitted" | "waitlisted";AccountTenantView
export type AccountTenantView = {
tenantId: TenantId;
label: string;
createdAt: number;
};AccountView
GET /v1/account
export type AccountView = {
subject: string;
email: string;
admission: AccountAdmission;
tenant: AccountTenantView | null;
};AccountTenantCreateRequest
POST /v1/account/tenant (header Idempotency-Key) → 201
export type AccountTenantCreateRequest = {
label: string;
};AccountTenantCreateResponse
export type AccountTenantCreateResponse = {
tenantId: TenantId;
};AccountKeyView
GET /v1/account/keys
export type AccountKeyView = {
keyId: string;
label: string;
scopes: Scope[];
createdAt: number;
expiresAt: number | null;
lastFour: string;
};AccountKeysResponse
export type AccountKeysResponse = {
keys: AccountKeyView[];
};AccountKeyCreateRequest
POST /v1/account/keys → 201. The plaintext key appears only here, once.
export type AccountKeyCreateRequest = {
label: string;
scopes: Scope[];
ttlDays?: number;
};AccountKeyCreateResponse
export type AccountKeyCreateResponse = {
keyId: string;
apiKey: ApiKey;
};AccountKeyRevokeResponse
POST /v1/account/keys/:keyId/revoke → 200
export type AccountKeyRevokeResponse = {
keyId: string;
revokedAt: number;
};AccountHabitatsResponse
GET /v1/account/habitats
export type AccountHabitatsResponse = {
habitats: HabitatView[];
next?: string;
};AccountCreditCheckoutRequest
POST /v1/account/credits/checkout
export type AccountCreditCheckoutRequest = {
amountMicrocents: number;
};AccountCreditCheckoutResponse
export type AccountCreditCheckoutResponse = {
checkoutUrl: string;
};AccountUsageResponse
GET /v1/account/usage
export type AccountUsageResponse = {
balanceMicrocents: number;
periodSpendMicrocents: number;
};AccountOrgResponse
GET /v1/account/org — the account's org slug, or `org: null`.
export type AccountOrgResponse = {
org: AccountOrgView | null;
};AccountOrgView
export type AccountOrgView = {
slug: string;
createdAt: number;
};AccountOrgRequest
POST /v1/account/org; PATCH /v1/account/org (rename while unbound).
export type AccountOrgRequest = {
slug: string;
};EndpointState
Endpoint lifecycle: live serves paid calls; paused refuses them; retired is terminal — a retired name can never be re-created or reactivated.
export type EndpointState = "live" | "paused" | "retired";AccountEndpointView
GET /v1/account/endpoints item.
export type AccountEndpointView = {
org: string;
project: string;
habitatId: string;
mailbox: string;
priceMicrocents: number;
packSize: number;
state: EndpointState;
createdAt: number;
updatedAt: number;
};AccountEndpointCreateRequest
POST /v1/account/endpoints → 201.
export type AccountEndpointCreateRequest = {
project: string;
habitatId: string;
mailbox: string;
priceMicrocents: number;
packSize: number;
};AccountEndpointPatchRequest
PATCH /v1/account/endpoints/:project — omitted fields are unchanged. `state` may be "live", "paused" or "retired"; retired is terminal.
export type AccountEndpointPatchRequest = {
priceMicrocents?: number;
packSize?: number;
state?: EndpointState;
};AccountEndpointsResponse
GET /v1/account/endpoints
export type AccountEndpointsResponse = {
endpoints: AccountEndpointView[];
next?: string;
};AccountEarningsEntry
GET /v1/account/earnings — the owner's journaled ledger view (W3-PAY). `availableMicrocents` is what apply/payout may draw: accrued − applied − paidOut − clawedBack.
export type AccountEarningsEntry = {
seq: number;
kind: string;
microcents: number;
ref: string;
at: number;
};AccountEarningsResponse
export type AccountEarningsResponse = {
accruedMicrocents: number;
appliedMicrocents: number;
paidOutMicrocents: number;
clawedBackMicrocents: number;
availableMicrocents: number;
connect?: {
accountId: string;
chargesEnabled: boolean;
payoutsEnabled: boolean;
};
entries: AccountEarningsEntry[];
next?: number;
};AccountEarningsApplyRequest
POST /v1/account/earnings/apply — move available earnings into the spendable broker balance. Idempotent on the Idempotency-Key header.
export type AccountEarningsApplyRequest = {
amountMicrocents: number;
};AccountEarningsApplyResponse
export type AccountEarningsApplyResponse = {
appliedMicrocents: number;
balanceMicrocents?: number;
duplicate?: boolean;
};AccountPayoutLinkResponse
POST /v1/account/payouts/link — Connect Express onboarding URL for the account's bound (or newly created) Stripe account.
export type AccountPayoutLinkResponse = {
url: string;
accountId: string;
};AccountPayoutRequest
POST /v1/account/payouts — transfer available earnings to the bound Connect account. `amountMicrocents` omitted pays the full available balance (floored to whole cents). Idempotent on Idempotency-Key.
export type AccountPayoutRequest = {
amountMicrocents?: number;
};AccountPayoutResponse
export type AccountPayoutResponse = {
paidOutMicrocents: number;
transferId?: string;
duplicate?: boolean;
};Platform limits
Generated from packages/protocol/src/index.ts. They apply to every early-access account and may change before launch.
| Limit | Value |
|---|---|
| Habitats per account | 64 |
| Processes per habitat | 1,024 |
| Mailboxes per habitat | 64 |
| Message size | 64,000 bytes |
| Program bundle size | 8 MiB |
| Generations per process | 64 |
| Wall time per step | 25 s |