HomeResourcesDeveloper resources

Developer resources

REST API, docs, guides, example code and the tools we use ourselves for automating Joy.

Getting an API token

Go to Console → Account → API tokens, give the token a name, choose scopes (read, orders.write, instances.write, billing.read, tickets.write) and optionally an expiry date and an IP allow-list. The secret is shown once; store it in your secrets manager, never in a repository. Tokens are hashed at rest, every call is logged, and you can revoke a token instantly.

Example: deploy from a script

TOKEN=joy_xxx
API=https://joy.services/api/v1

# quote first (no charge)
curl -s -X POST $API/quote -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"location":"mumbai","os":"ubuntu-24","plan":"small","cycle":"hourly"}'

# deploy from wallet balance
curl -s -X POST $API/instances -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"location":"mumbai","os":"ubuntu-24","plan":"small","cycle":"hourly","hostname":"ci-01","pay":"wallet"}'

# poll the job returned above until status is "done"
curl -s $API/jobs/1842 -H "Authorization: Bearer $TOKEN"

Conventions worth knowing

  • Every response has ok; errors carry error and status.
  • Money is USD as a float; local amounts are labelled with currency.
  • Instance ids are opaque 32-character hashes; never rely on VMIDs.
  • Asynchronous actions return a job id — poll /jobs/{id} every 2–5 s.
  • Rate limit 600 requests / minute per token; deployments 10 / hour; tickets 5 / hour.
  • Use hourly billing as your sandbox: a full test cycle costs less than a cent.
  • v1 is additive — fields are added, never removed or renamed.
  • Legacy /api/connect keeps working for existing token/key pairs.

Recipes

CI runners on demand

Create a Small server with cycle: hourly when a pipeline starts, bootstrap it with cloud-init-style scripts over SSH using the key you passed in ssh_key, and DELETE it when the job finishes. Cost per run: a few paise.

Nightly snapshots

A cron job calls POST /instances/{id}/snapshot with {"op":"create","name":"nightly-YYYYMMDD"} and deletes the one from a week ago. Free, instant, and reversible with rollback.

Status in Slack / Grafana

Poll /status.json every minute; post to Slack when overall changes, or graph the components array as a state timeline.

Fleet inventory

GET /instances gives hostname, IP, location, spec, billing and live stats for every server — enough to feed an asset database or a cost dashboard without agents.

Reinstall on schedule

Test environments that must start clean every Monday: POST /instances/{id}/reinstall with the OS code; the IP stays and the new password is in GET /instances/{id}.

Password rotation

POST /instances/{id}/password generates and applies a new root / Administrator password through the guest agent — 3 per 10 minutes per server.

Tooling

There is no official SDK yet — the API is small enough that a 30-line wrapper in your language of choice is usually better than a dependency; the reference includes complete PHP and JavaScript clients you can copy. A Terraform provider and webhooks are on the roadmap and will be announced in Updates. If you build something on the API that others could use, tell us: we link to community tools from this page and credit the author with wallet balance.

Security guidance

  • Keep tokens server-side. Never call the API from a browser or a mobile app.
  • Use the smallest scope set that works and an IP allow-list for hosts with fixed addresses.
  • Rotate tokens when people leave the team; the API log shows the last use of every token.
  • Report vulnerabilities to security@joy.services — see the Trust Center.

Ready to build?

Create an account, verify your email, deploy in under 90 seconds — or talk to us first.