Aetherfy account and usage API
Base URL https://agents.aetherfy.com/api/v1, bearer authentication, and the shared
error envelope are described on the Agent REST API index.
Reading the authenticated Aetherfy identity
GET /api/v1/auth/me → 200
curl -s https://agents.aetherfy.com/api/v1/auth/me \
-H "Authorization: Bearer $AETHERFY_API_KEY"{
"user_id": "2f9c6b18-0a53-47e2-9d81-4b7c0e35a6f2",
"email": "[email protected]",
"tier": "performance",
"subscription_status": "active",
"is_test": false,
"limits": {"requests_per_minute": 2000, "max_regions": 3, "…": "…"}
}This is the cheapest way to verify a key works, and the only route that answers “which
environment am I in” — is_test is true for an afy_test_ key and false for an
afy_live_ one. It is derived from the key itself, not from anything you send.
limits is the plan’s live limit object. Read your rate budget from
limits.requests_per_minute rather than hardcoding a plan’s number: it is the value
the limiter actually enforces for this account, so it stays correct across plan
changes. On Enterprise it is null, meaning unlimited.
This route needs only a valid key — it does not touch your resources, so it answers even when everything else is refusing.
Reading Aetherfy agent lifecycle events
GET /api/v1/usage/agent/{agent_id}/events → 200
Machine start and stop events for one agent — the raw material behind the awake
time it is billed for, useful for reconciling a surprising figure. Takes ?limit
and, unlike most routes, requires the agent’s UUID rather than accepting a
name.
There is no per-agent usage summary endpoint. Your account’s usage for the current period, per agent, is on the usage meter ; how it is priced is in Billing and spend caps.
Returns 403 AGENT_NOT_FOUND for an unknown agent or one belonging to another
account: this route answers 403 where the agent routes answer 404, so match on the
code rather than the status.
Connecting a GitHub account to Aetherfy
Push-to-deploy needs two steps: connect the account once, here, then link each agent to a repository with the routes on Deployments.
GET /api/v1/auth/github/status → 200
curl -s https://agents.aetherfy.com/api/v1/auth/github/status \
-H "Authorization: Bearer $AETHERFY_API_KEY"{"connected": true, "installations": [{"installation_id": 12345678, "account_id": 330816932, "account_login": "acme", "account_type": "Organization", "connected_at": "2026-08-19T09:00:00Z", "manage_url": "https://github.com/organizations/acme/settings/installations/12345678"}, {"installation_id": 12345679, "account_id": 170044470, "account_login": "octocat", "account_type": "User", "connected_at": "2026-08-20T11:30:00Z", "manage_url": "https://github.com/settings/installations/12345679"}]}installations is a list because one Aetherfy account can hold several GitHub
installations — your personal account, and one for each organization whose
installation GitHub shows the person who connected.
Each agent deploys through the installation whose repositories include the one it is
linked to, so disconnecting one account stops only the agents on its repositories.
account_login is the GitHub account an installation is on, and account_type is
GitHub’s own word for what kind it is — "User" or "Organization", passed through
so the wording you show is yours to choose. Neither is necessarily the account you
sign in with. They are read live from GitHub where it can be reached, so an account
rename shows correctly.
manage_url is that installation’s own settings page on GitHub, where a connected
user adds or removes repositories. Its shape follows account_type, which is why it
is read from GitHub rather than built. It is not the App’s install page: that one
asks which account to authorize.
manage_url is null when Aetherfy could not reach GitHub. connected comes from
Aetherfy’s own records and stays authoritative either way; it is exactly “holds at
least one installation”.
GET /api/v1/auth/github begins the connection and returns {"connect_url": "..."},
a github.com address. Call it with your key, then open that URL in a browser. The
route needs your API key like any other, so a browser pointed straight at it answers
401 MISSING_API_KEY — fetch the URL first, navigate second. There is no way to
complete a connection from the API alone: a human has to authorize it on GitHub, and
GitHub redirects back to Aetherfy afterwards. Returns 501
GITHUB_APP_NOT_CONFIGURED where the integration is unavailable.
curl -s https://agents.aetherfy.com/api/v1/auth/github -H "Authorization: Bearer $AETHERFY_API_KEY"{"connect_url": "https://github.com/login/oauth/authorize?client_id=...&state=...", "expires_at": "2026-08-19T09:10:00Z"}connect_url is GitHub’s authorize page, not the App’s install page. Authorizing
always returns you to Aetherfy, which is what lets an installation that already
exists be attached; if the App is installed nowhere yet, GitHub asks where to install
it first. Calling this again on a connected account is how you add a second GitHub
account — it never replaces the ones you have.
expires_at bounds the URL: the state token it carries is refused from that instant,
so opening the URL later records nothing. Ask this route for a fresh URL rather than
reusing an expired one.
DELETE /api/v1/auth/github/installations/{installation_id} → 204 disconnects ONE
GitHub account. Agents linked to its repositories stop deploying on push; their links
are kept, so reconnecting that account resumes them. Agents deploying through your
other installations are untouched. Returns 404 GITHUB_INSTALLATION_NOT_FOUND if your
account does not hold that installation.
DELETE /api/v1/auth/github → 204 disconnects every installation at once.
Listing the repositories Aetherfy can link
GET /api/v1/auth/github/repositories → 200
{"repositories": [{"full_name": "acme/api", "private": true, "default_branch": "main", "installation_id": 12345678, "account_login": "acme", "account_type": "Organization"}]}The union across every installation the account holds, sorted by full_name, each
repository carrying the account it belongs to. This is the domain of the link route’s
repo field: linking registers a webhook on the repository, so one outside this list
cannot be linked. Returns 422 GITHUB_NOT_CONNECTED when the account holds no live
installation.
The callback and webhook routes that complete this flow —
/api/v1/auth/github/oauth/callback, /api/v1/auth/github/callback and
/api/v1/webhooks/github — are called by GitHub, not by you, and are authenticated by
signature or by a one-time state token rather than by your API key.
See GitHub integration.