IPXdocs
API reference

API reference

Everything you do in the console is a call away. Browse listings, register a key, rent a GPU, and watch the meter, all over one JSON API and a single bearer token.

The API drives the whole platform. You list price-sorted GPUs, push an SSH public key, rent a box, poll it until your connection string appears, then tear it down. There is no provider account, no quota dance, and no second credential to manage. Authenticate every request with one token and you are in.

Base URL

Every endpoint lives under /api/v1 on the IPX origin. There is one version and it is v1.

base url
https://gpu.ipxtechholding.com/api/v1

In the examples below we keep the origin in a shell variable so you can copy a request and run it as-is.

bash
$ export IPX_BASE="https://gpu.ipxtechholding.com"
$ curl "$IPX_BASE/api/v1/listings"

Authentication

The API uses named bearer tokens, created under Settings → API access. Each token starts with ipx_, is shown once at creation, and can be revoked individually at any time. We store only a SHA-256 digest, so if you lose one you create a new one rather than recover it.

Send it in the Authorization header on every authenticated request, prefixed with Bearer. We document it below as the shell variable $IPX_TOKEN.

authorization header
# store your token once, then reuse it
$ export IPX_TOKEN="ipx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# send it on every authenticated call
$ curl "$IPX_BASE/api/v1/credits" \\
    -H "Authorization: Bearer $IPX_TOKEN"

Workspaces and roles

Every token belongs to one workspace: your personal workspace or a team you are a member of. Requests act inside that workspace and carry your live role there, exactly like the console.

  • Developer: rent and terminate boxes, manage SSH keys, read the balance.
  • Admin and owner: everything above, plus opening credit top-ups.

The role is checked on every request, not stamped into the token. Leave a team and its tokens stop working immediately; get promoted and your existing token gains the new powers. A token whose action exceeds your role returns 403 Forbidden.

Treat tokens like passwords. They can rent hardware and spend the workspace balance. Never commit them or paste them into client-side code. If one leaks, revoke it in Settings; revocation is immediate. For CI and short-lived automation, create tokens with a 30 or 90 day expiry.

Which endpoints need a token

Listings are public, so you can browse prices before you sign in. Everything that touches a workspace, its keys, or its money requires a valid bearer token.

  • Public: GET /api/v1/listings
  • Authenticated: SSH keys, rentals, and credits

Authentication errors

If the Authorization header is missing, malformed, expired, revoked, or no longer matches a workspace membership, the request is rejected with 401 Unauthorized and a JSON error body. No partial work is done. A valid token used beyond its role returns 403.

response · 401
// a missing, invalid, expired, or revoked token, on any authenticated endpoint
{
  "error": "unauthorized"
}

Rate limits

Authenticated calls are limited to 120 requests per minute per token. Past the limit you get 429 Too Many Requests; back off briefly and retry. Registration and other credential endpoints have tighter limits.

Conventions

JSON in, JSON out

Requests and responses are JSON. Send parameters as query string or form body, and you always get a JSON object back, including on errors. There is no XML and no envelope to unwrap. Collection endpoints return a named array, for example { "listings": [ ... ] }.

Money is micro-USD

All amounts are integers in micro-USD, where 1 USD = 1,000,000 micro. Integers keep money exact, with no floating-point drift. Convert by dividing or multiplying by one million.

  • 680000 is $0.68
  • 5000000 is a $5.00 spend cap
  • 1000000 is $1.00

Listings expose both forms for convenience. price_micro_usd_per_hour is the exact integer you should compute against, and price_usd_per_hour is a rounded decimal for display only. Everywhere else, the field name carries the unit, for example accumulated_cost_micro_usd, max_cost_micro_usd, and balance_micro_usd.

One exception: when you top up credits, Stripe works in cents, so the credit endpoint takes amount_cents rather than micro-USD. The credits page covers that in full.

Status codes

We use standard HTTP status codes. A 2xx means it worked, a 4xx means the request was wrong, and a 5xx or 502 means something failed upstream. Error bodies are always { "error": "message" }.

200 · OKsuccess
The request succeeded. Returned by reads such as GET /api/v1/rentals/:id and by a termination.
201 · Createdsuccess
A resource was created. Returned when you register an SSH key, start a rental, or open a credit top-up.
401 · Unauthorizedauth
The bearer token is missing, malformed, or unknown. Check the Authorization header.
402 · Payment Requiredcredit
Not enough credit to start the rental. Top up, then retry. You can never be charged past your balance.
403 · Forbiddenpermission
The action exceeds your role in the token's workspace, or you referenced a resource you do not own.
404 · Not Foundmissing
No such resource, or it is not yours to see. A rental id from another account reads as not found.
409 · Conflictunavailable
The listing was claimed or pulled before your rental landed. Pick another box from the feed.
422 · Unprocessableinvalid
A parameter failed validation, for example a malformed SSH public key. The message names the problem.
429 · Too Many Requeststhrottle
You passed the per-token rate limit of 120 requests per minute. Back off briefly and retry.
502 · Bad Gatewayupstream
A cloud provider rejected or dropped the request while provisioning. Safe to retry.
response · error shape
// every non-2xx carries the same minimal shape
{
  "error": "insufficient credit to start this rental"
}

The rental lifecycle

Renting is asynchronous. A successful POST /api/v1/rentals returns 201 immediately with a state of provisioning_requested, then the box boots and dials home. Poll GET /api/v1/rentals/:id until the state reaches active_connected, at which point a connection_string appears.

rental states
provisioning_requested  ->  booting_instance  ->  awaiting_tunnel
                                                        |
                                                        v
                        terminated  <-  terminating  <-  active_connected

The connection_string field is null until the tunnel is live, then becomes a ready-to-run command like ssh -p 20137 root@gpu.ipxtechholding.com. Poll on a short interval and stop as soon as it is non-null. The rentals page has a complete poll loop.

A first call

Listings are public, so this works before you even hold a token. It confirms your base URL is right and shows the money fields in context.

terminal
$ curl "https://gpu.ipxtechholding.com/api/v1/listings?limit=1"
response · 200
{
  "listings": [
    {
      "id": 4812,
      "gpu_name": "RTX 4090",
      "vram_gb": 24,
      "num_gpus": 1,
      "region": "us-east",
      "interruptible": false,
      "price_micro_usd_per_hour": 680000,
      "price_usd_per_hour": 0.68
    }
  ]
}

Resources

Four resources cover the whole platform. Start with SSH keys and listings, then rentals, then credits when you need to top up.

Next steps