Joy Services
All systems operational Sign in
JoyResourcesDeveloper resources
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.
Next step

Ready to build? Deploy in under 90 seconds — or talk to us first.