Skip to content

[FEATURE] Add idempotency support for billable order and VPS purchase endpoints #49

@coygeek

Description

@coygeek

Feature Description

Please add documented idempotency support for billable operations, especially:

POST /api/vps/v1/virtual-machines
POST /api/billing/v1/orders

For example, support an Idempotency-Key header and return the original result when the same key is retried.

Problem Statement

Agentic and CI-style workflows commonly run across flaky networks, process restarts, and retry loops. For non-billable operations, retrying is usually safe. For purchase/order endpoints, retrying can accidentally create duplicate billable resources unless the API provides an idempotency contract.

Without documented idempotency, clients have to build weaker workarounds such as:

  • searching inventory by hostname after a timeout
  • comparing recent orders/subscriptions
  • sleeping and polling before retrying
  • asking a human to resolve ambiguous purchase state

Those workarounds are fragile and hard to make safe.

Proposed Solution

Document and support a header such as:

Idempotency-Key: 2f2e8f70-46d3-4a4a-a828-example

For a repeated request with the same key and same body, the API should return the original order/virtual-machine response instead of creating a duplicate resource.

For a repeated request with the same key and a different body, the API should return a clear conflict error.

It would also help to document:

  • retention window for idempotency keys
  • which endpoints support idempotency
  • whether idempotency is scoped by API token/account
  • response behavior while the original operation is still processing

Use Cases

  • Retry safely after client timeouts.
  • Resume an interrupted agent run without creating duplicate VPSs.
  • Build reliable automation around billable Hostinger resources.
  • Avoid manual billing cleanup after ambiguous network failures.

Additional Context

The VPS purchase response already has a useful shape with both order and virtual_machine. Idempotency would make that response safe to recover after transient failures.

Are you willing to contribute?

  • Yes, I'd like to implement this feature
  • Yes, but I need guidance
  • No, but I'm available for testing
  • No

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions