Skip to content

API reference

Billing and usage API

Balances, limits, metered usage, invoice preview, and billing management.

On this page

Get billing

GET /v1/billing

  • API key: Authorization: Bearer vmy_… with preset read_only, use_existing, create_and_use, full_access.
  • Browser session: the vmyard_session cookie.
  • Who: Any member.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200—BillingDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
Request
curl "$VMYARD_API_URL/v1/billing" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "balances": {
    "credit_micros": 0,
    "plan_micros": 0,
    "spendable_micros": 0,
    "trial_micros": 0
  },
  "card_check": {
    "required": false,
    "verified_at": "string"
  },
  "credit_spent_this_month_micros": 0,
  "currency": "USD",
  "exhausted_since": "string",
  "limits": {
    "concurrent_machines": {
      "limit": 0,
      "used": 0
    },
    "starts": [
      {
        "limit": 0,
        "used": 0,
        "window": "hour"
      }
    ],
    "status": "trial",
    "tier": "pro"
  },
  "minimum_balance_micros": 0,
  "organization_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "payment_customer_linked": false,
  "payments_available": false,
  "plan": {
    "active": false,
    "cancel_at_period_end": false,
    "included_micros": 0,
    "included_seconds": 0,
    "period_end": "string",
    "period_start": "string",
    "price_micros": 0,
    "renews": false,
    "tier": "pro"
  },
  "spend_cap_micros": 0,
  "status": "trial",
  "trial": {
    "active": false,
    "concurrent_machines": 0,
    "ended_at": "string",
    "max_hourly_micros": 0,
    "remaining_micros": 0,
    "remaining_seconds": 0,
    "total_micros": 0
  }
}

Change billing settings

PATCH /v1/billing

  • API key: Authorization: Bearer vmy_… with preset full_access.
  • Browser session: the vmyard_session cookie and the x-csrf-token header.
  • Who: Owner or Billing.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Request body (application/json, UpdateBillingRequest)

FieldTypeRequiredDescription
minimum_balance_microsinteger | nullNo
spend_cap_microsinteger | nullNoMonthly credit spend cap in micros, or null to remove it.

Responses

StatusDescriptionBody
200—BillingDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
403Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required).ProblemDetails
422Invalid request (invalid_request); field_errors names the fields.ProblemDetails
Request
curl -X PATCH "$VMYARD_API_URL/v1/billing" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "spend_cap_micros": 100000000,
  "minimum_balance_micros": 0
}'
Response 200
{
  "balances": {
    "credit_micros": 0,
    "plan_micros": 0,
    "spendable_micros": 0,
    "trial_micros": 0
  },
  "card_check": {
    "required": false,
    "verified_at": "string"
  },
  "credit_spent_this_month_micros": 0,
  "currency": "USD",
  "exhausted_since": "string",
  "limits": {
    "concurrent_machines": {
      "limit": 0,
      "used": 0
    },
    "starts": [
      {
        "limit": 0,
        "used": 0,
        "window": "hour"
      }
    ],
    "status": "trial",
    "tier": "pro"
  },
  "minimum_balance_micros": 0,
  "organization_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "payment_customer_linked": false,
  "payments_available": false,
  "plan": {
    "active": false,
    "cancel_at_period_end": false,
    "included_micros": 0,
    "included_seconds": 0,
    "period_end": "string",
    "period_start": "string",
    "price_micros": 0,
    "renews": false,
    "tier": "pro"
  },
  "spend_cap_micros": 0,
  "status": "trial",
  "trial": {
    "active": false,
    "concurrent_machines": 0,
    "ended_at": "string",
    "max_hourly_micros": 0,
    "remaining_micros": 0,
    "remaining_seconds": 0,
    "total_micros": 0
  }
}

Start a checkout

POST /v1/billing/checkout

  • API key: Authorization: Bearer vmy_… with preset full_access.
  • Browser session: the vmyard_session cookie and the x-csrf-token header.
  • Who: Owner or Billing.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Request body (application/json, CheckoutRequestDto)

FieldTypeRequiredDescription
credit_packsinteger | nullNoBuy this many $20 credit packs (1-50).
end_trialbooleanNoWith plan: forfeit the remaining trial once the plan's first payment is confirmed, so the plan's allowance is used right away.
planstring | nullNoSubscribe to starter, pro, team, or scale.

Responses

StatusDescriptionBody
201—CheckoutDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
403Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required).ProblemDetails
422Invalid request (invalid_request); field_errors names the fields.ProblemDetails
501billing_unavailable: payments are not configuredProblemDetails
502payment_provider_errorProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/billing/checkout" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "credit_packs": 2
}'
Response 201
{
  "checkout_url": "string",
  "session_id": "string"
}

Open the payment portal

POST /v1/billing/portal

  • API key: Authorization: Bearer vmy_… with preset full_access.
  • Browser session: the vmyard_session cookie and the x-csrf-token header.
  • Who: Owner or Billing.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
201—PortalDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
403Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required).ProblemDetails
409billing_customer_missing: no purchase has linked a payment customer yetProblemDetails
501billing_unavailable: payments are not configuredProblemDetails
502payment_provider_errorProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/billing/portal" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 201
{
  "url": "https://hooks.example.com/vmyard"
}

Verify a card for the trial

POST /v1/billing/card-check

Start a card check: a hosted setup page where a billing manager enters a card, which the provider verifies (and screens for fraud) without charging it. The signed checkout.session.completed webhook records the verification; until then a trial cannot start machines when the service requires a card (402 card_verification_required).

Opens the payment provider's page where a card is checked, not charged. When card_check.required is true on GET /v1/billing, a trial can't create, start, or restart machines (402 card_verification_required) until the check completes. See Usage, billing, and limits.

  • API key: Authorization: Bearer vmy_… with preset full_access.
  • Browser session: the vmyard_session cookie and the x-csrf-token header.
  • Who: Owner or Billing.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
201—CardCheckSessionDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
403Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required).ProblemDetails
501billing_unavailable: payments are not configuredProblemDetails
502payment_provider_errorProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/billing/card-check" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 201
{
  "checkout_url": "string",
  "session_id": "string"
}

Cancel the plan at period end

POST /v1/billing/subscription/cancel

The plan keeps its allowance until plan.period_end, then ends. See Cancel a plan or end the trial.

  • API key: Authorization: Bearer vmy_… with preset full_access.
  • Browser session: the vmyard_session cookie and the x-csrf-token header.
  • Who: Owner or Billing.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200The plan stays active until plan.period_end, then endsBillingDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
403Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required).ProblemDetails
409subscription_missing: no renewing subscription is linkedProblemDetails
501billing_unavailableProblemDetails
502payment_provider_errorProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/billing/subscription/cancel" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "balances": {
    "credit_micros": 0,
    "plan_micros": 0,
    "spendable_micros": 0,
    "trial_micros": 0
  },
  "card_check": {
    "required": false,
    "verified_at": "string"
  },
  "credit_spent_this_month_micros": 0,
  "currency": "USD",
  "exhausted_since": "string",
  "limits": {
    "concurrent_machines": {
      "limit": 0,
      "used": 0
    },
    "starts": [
      {
        "limit": 0,
        "used": 0,
        "window": "hour"
      }
    ],
    "status": "trial",
    "tier": "pro"
  },
  "minimum_balance_micros": 0,
  "organization_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "payment_customer_linked": false,
  "payments_available": false,
  "plan": {
    "active": false,
    "cancel_at_period_end": false,
    "included_micros": 0,
    "included_seconds": 0,
    "period_end": "string",
    "period_start": "string",
    "price_micros": 0,
    "renews": false,
    "tier": "pro"
  },
  "spend_cap_micros": 0,
  "status": "trial",
  "trial": {
    "active": false,
    "concurrent_machines": 0,
    "ended_at": "string",
    "max_hourly_micros": 0,
    "remaining_micros": 0,
    "remaining_seconds": 0,
    "total_micros": 0
  }
}

Resume a cancelled plan

POST /v1/billing/subscription/resume

  • API key: Authorization: Bearer vmy_… with preset full_access.
  • Browser session: the vmyard_session cookie and the x-csrf-token header.
  • Who: Owner or Billing.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200The plan renews again at plan.period_endBillingDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
403Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required).ProblemDetails
409subscription_missing: the subscription already endedProblemDetails
501billing_unavailableProblemDetails
502payment_provider_errorProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/billing/subscription/resume" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "balances": {
    "credit_micros": 0,
    "plan_micros": 0,
    "spendable_micros": 0,
    "trial_micros": 0
  },
  "card_check": {
    "required": false,
    "verified_at": "string"
  },
  "credit_spent_this_month_micros": 0,
  "currency": "USD",
  "exhausted_since": "string",
  "limits": {
    "concurrent_machines": {
      "limit": 0,
      "used": 0
    },
    "starts": [
      {
        "limit": 0,
        "used": 0,
        "window": "hour"
      }
    ],
    "status": "trial",
    "tier": "pro"
  },
  "minimum_balance_micros": 0,
  "organization_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "payment_customer_linked": false,
  "payments_available": false,
  "plan": {
    "active": false,
    "cancel_at_period_end": false,
    "included_micros": 0,
    "included_seconds": 0,
    "period_end": "string",
    "period_start": "string",
    "price_micros": 0,
    "renews": false,
    "tier": "pro"
  },
  "spend_cap_micros": 0,
  "status": "trial",
  "trial": {
    "active": false,
    "concurrent_machines": 0,
    "ended_at": "string",
    "max_hourly_micros": 0,
    "remaining_micros": 0,
    "remaining_seconds": 0,
    "total_micros": 0
  }
}

End the trial early

POST /v1/billing/trial/end

End the trial now: its remaining balance is forfeited (a trial_forfeit ledger row) and cannot be restored. Trial rules (two machines, small/default sizes) still apply until the first payment. Ending an ended trial changes nothing.

Forfeits the remaining trial balance for good; trial rules apply until the first payment. See Cancel a plan or end the trial.

  • API key: Authorization: Bearer vmy_… with preset full_access.
  • Browser session: the vmyard_session cookie and the x-csrf-token header.
  • Who: Owner or Billing.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200—BillingDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
403Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required).ProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/billing/trial/end" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "balances": {
    "credit_micros": 0,
    "plan_micros": 0,
    "spendable_micros": 0,
    "trial_micros": 0
  },
  "card_check": {
    "required": false,
    "verified_at": "string"
  },
  "credit_spent_this_month_micros": 0,
  "currency": "USD",
  "exhausted_since": "string",
  "limits": {
    "concurrent_machines": {
      "limit": 0,
      "used": 0
    },
    "starts": [
      {
        "limit": 0,
        "used": 0,
        "window": "hour"
      }
    ],
    "status": "trial",
    "tier": "pro"
  },
  "minimum_balance_micros": 0,
  "organization_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "payment_customer_linked": false,
  "payments_available": false,
  "plan": {
    "active": false,
    "cancel_at_period_end": false,
    "included_micros": 0,
    "included_seconds": 0,
    "period_end": "string",
    "period_start": "string",
    "price_micros": 0,
    "renews": false,
    "tier": "pro"
  },
  "spend_cap_micros": 0,
  "status": "trial",
  "trial": {
    "active": false,
    "concurrent_machines": 0,
    "ended_at": "string",
    "max_hourly_micros": 0,
    "remaining_micros": 0,
    "remaining_seconds": 0,
    "total_micros": 0
  }
}

Get automatic refill

GET /v1/billing/auto-refill

  • API key: Authorization: Bearer vmy_… with preset read_only, use_existing, create_and_use, full_access.
  • Browser session: the vmyard_session cookie.
  • Who: Any member.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200—AutoRefillDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
Request
curl "$VMYARD_API_URL/v1/billing/auto-refill" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "amount_micros": 0,
  "charged_this_month_micros": 0,
  "consecutive_failures": 0,
  "credit_packs": 0,
  "disabled_reason": "string",
  "enabled": false,
  "last_charge": {
    "amount_micros": 0,
    "created_at": "string",
    "credit_packs": 0,
    "failure_code": "string",
    "id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
    "status": "string"
  },
  "monthly_cap_micros": 0,
  "threshold_micros": 0
}

Change automatic refill

PUT /v1/billing/auto-refill

Configure automatic refill. Enabling needs online payments, a linked customer, and a default payment method at the provider; it also clears the failure count of a refill that turned itself off.

All four fields are required. Enabling needs a linked customer and a default card at the payment provider. See Automatic refill.

  • API key: Authorization: Bearer vmy_… with preset full_access.
  • Browser session: the vmyard_session cookie and the x-csrf-token header.
  • Who: Owner or Billing.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Request body (application/json, UpdateAutoRefillRequest)

FieldTypeRequiredDescription
credit_packsintegerYes1-50 packs of $20. 1–50.
enabledbooleanYes
monthly_cap_microsintegerYesAt least one refill's amount.
threshold_microsintegerYes

Responses

StatusDescriptionBody
200—AutoRefillDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
403Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required).ProblemDetails
409billing_customer_missing or payment_method_missing (set a default card in the portal)ProblemDetails
422Invalid request (invalid_request); field_errors names the fields.ProblemDetails
501billing_unavailableProblemDetails
502payment_provider_errorProblemDetails
Request
curl -X PUT "$VMYARD_API_URL/v1/billing/auto-refill" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "credit_packs": 1,
  "enabled": false,
  "monthly_cap_micros": 0,
  "threshold_micros": 0
}'
Response 200
{
  "amount_micros": 0,
  "charged_this_month_micros": 0,
  "consecutive_failures": 0,
  "credit_packs": 0,
  "disabled_reason": "string",
  "enabled": false,
  "last_charge": {
    "amount_micros": 0,
    "created_at": "string",
    "credit_packs": 0,
    "failure_code": "string",
    "id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
    "status": "string"
  },
  "monthly_cap_micros": 0,
  "threshold_micros": 0
}

Preview the invoice

GET /v1/billing/invoice-preview

  • API key: Authorization: Bearer vmy_… with preset read_only, use_existing, create_and_use, full_access.
  • Browser session: the vmyard_session cookie.
  • Who: Any member.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200—InvoicePreviewDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
Request
curl "$VMYARD_API_URL/v1/billing/invoice-preview" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "applied": {
    "credit_micros": 0,
    "plan_micros": 0,
    "trial_micros": 0
  },
  "credit_balance_micros": 0,
  "currency": "USD",
  "lines": [
    {
      "amount_micros": 0,
      "description": "default · machine time",
      "hourly_micros": 0,
      "multiplier": 0.5,
      "plan_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
      "plan_version": 0,
      "seconds": 0
    }
  ],
  "next_charge_micros": 0,
  "period_end": "string",
  "period_start": "string",
  "plan": {
    "active": false,
    "cancel_at_period_end": false,
    "included_micros": 0,
    "included_seconds": 0,
    "period_end": "string",
    "period_start": "string",
    "price_micros": 0,
    "renews": false,
    "tier": "pro"
  },
  "unbilled_micros": 0,
  "usage_micros": 0
}

Get limits

GET /v1/limits

  • API key: Authorization: Bearer vmy_… with preset read_only, use_existing, create_and_use, full_access.
  • Browser session: the vmyard_session cookie.
  • Who: Any member.

Parameters

NameInTypeRequiredDescription
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200—LimitsDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
Request
curl "$VMYARD_API_URL/v1/limits" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "concurrent_machines": {
    "limit": 0,
    "used": 0
  },
  "starts": [
    {
      "limit": 0,
      "used": 0,
      "window": "hour"
    }
  ],
  "status": "trial",
  "tier": "pro"
}

Get organization usage

GET /v1/usage

  • API key: Authorization: Bearer vmy_… with preset read_only, use_existing, create_and_use, full_access.
  • Browser session: the vmyard_session cookie.
  • Who: Any member.

Parameters

NameInTypeRequiredDescription
sincequerystringNoRFC 3339 start (inclusive). Defaults to the current plan period's start, or the UTC month's start without a plan; for one machine, to its first run.
untilquerystringNoRFC 3339 end (exclusive). Defaults to now.
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200—UsageDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
422Invalid request (invalid_request); field_errors names the fields.ProblemDetails
Request
curl "$VMYARD_API_URL/v1/usage" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "cost_micros": 0,
  "machines": [
    {
      "cost_micros": 0,
      "hourly_micros": 0,
      "machine_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
      "multiplier": 0.5,
      "running": false,
      "seconds": 0
    }
  ],
  "seconds": 0,
  "since": "string",
  "until": "string"
}

Get machine usage

GET /v1/machines/{machine_id}/usage

  • API key: Authorization: Bearer vmy_… with preset read_only, use_existing, create_and_use, full_access.
  • Browser session: the vmyard_session cookie.
  • Who: Any member.

Parameters

NameInTypeRequiredDescription
machine_idpathstring (uuid)Yes
sincequerystringNoRFC 3339 start (inclusive). Defaults to the current plan period's start, or the UTC month's start without a plan; for one machine, to its first run.
untilquerystringNoRFC 3339 end (exclusive). Defaults to now.
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200—MachineUsageDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
404Not found in this organization (resource_not_found).ProblemDetails
422Invalid request (invalid_request); field_errors names the fields.ProblemDetails
Request
curl "$VMYARD_API_URL/v1/machines/$MACHINE_ID/usage" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "cost_micros": 0,
  "hourly_micros": 0,
  "machine_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "multiplier": 0.5,
  "running": false,
  "seconds": 0
}

Receive a Stripe event

POST /v1/billing/stripe/webhook

Stripe calls this with signed events. It needs no session or API key: the signature over the exact body is the authentication.

  • Authentication: none on this route.
  • Who: Stripe (signed request).

Parameters

NameInTypeRequiredDescription
Stripe-SignatureheaderstringYest=<unix seconds>,v1=<hex HMAC-SHA256>

Request body (application/json)

No fields.

Responses

StatusDescriptionBody
200—WebhookAckDto
400invalid_signature or invalid_eventProblemDetails
501billing_unavailableProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/billing/stripe/webhook" \
  -H "Stripe-Signature: $STRIPE_SIGNATURE" \
  -H "Content-Type: application/json" \
  -d '"string"'
Response 200
{
  "outcome": "applied",
  "received": false
}

Grant credits or time (operators)

POST /v1/operator/billing/grants

Operators grant credits, trial time, or plan periods by hand (support, invoices paid offline, or a deployment without online payments). The caller presents the operator token configured for the service; members of an organization, however privileged, cannot reach it.

  • Authentication: none on this route.
  • Who: Service operators (operator token).

Parameters

NameInTypeRequiredDescription
X-VMYard-Operator-TokenheaderstringYesOperator token from the service configuration

Request body (application/json, OperatorGrantRequest)

FieldTypeRequiredDescription
idempotency_keystringYesReplaying the same key applies the grant once.
kindGrantKindDtoYes
organization_idstring (uuid)Yes
reasonstringYesWhy the grant was made; recorded in the audit log.
amount_microsinteger | nullNoMicros for credits and trial.
period_daysinteger | nullNoPeriod length for plan_period, starting now (1-366, default 30).
tierstring | nullNoTier for plan_period.

Responses

StatusDescriptionBody
200—GrantResultDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
404operator grants are not configured or the organization is unknownProblemDetails
422Invalid request (invalid_request); field_errors names the fields.ProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/operator/billing/grants" \
  -H "X-VMYard-Operator-Token: $X_VMYARD_OPERATOR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "organization_id": "2a7d4c1e-8b3f-4f6a-9c5d-0e1f2a3b4c5d",
  "kind": "credits",
  "amount_micros": 20000000,
  "reason": "Invoice 1042 paid by bank transfer",
  "idempotency_key": "grant-invoice-1042"
}'
Response 200
{
  "outcome": "applied"
}

List wallet movements

GET /v1/billing/ledger

The wallet's movements other than usage (grants, credits from VMYard, purchases, expiries), newest first. Usage is reported by /v1/usage.

Grants, credits from VMYard, purchases, and expiries, newest first. Usage is in GET /v1/usage.

  • API key: Authorization: Bearer vmy_… with preset read_only, use_existing, create_and_use, full_access.
  • Browser session: the vmyard_session cookie.
  • Who: Any member.

Parameters

NameInTypeRequiredDescription
limitqueryintegerNo1-100, default 50.
beforequeryintegerNoEntries before this one (next_before of the previous page).
X-Organization-IDheaderstring (uuid)NoRequired with a browser session. Optional with an API key, which fixes the organization; when sent it must match.

Responses

StatusDescriptionBody
200—LedgerPage
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
422Invalid request (invalid_request); field_errors names the fields.ProblemDetails
Request
curl "$VMYARD_API_URL/v1/billing/ledger" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
Response 200
{
  "items": [
    {
      "amount_micros": 0,
      "at": "string",
      "bucket": "string",
      "id": 0,
      "kind": "trial_grant",
      "label": "k7f2mq3x9a1b",
      "plan_tier": "string"
    }
  ],
  "next_before": 0
}

Grant credits from VMYard (operators)

POST /v1/operator/billing/credits

Grant credits from VMYard to an organization, or claw them back. They are a gift, not a payment: the organization's status (and trial rules) do not change. The organization sees each as "Credit from VMYard" in GET /v1/billing/ledger.

  • Authentication: none on this route.
  • Who: Service operators (operator token).

Parameters

NameInTypeRequiredDescription
X-VMYard-Operator-TokenheaderstringYesOperator token from the service configuration

Request body (application/json, OperatorCreditRequest)

FieldTypeRequiredDescription
amount_microsintegerYesPositive micros (1 USD = 1000000). at least 1.
idempotency_keystringYesReplaying the same key applies the change once.
kindCreditKindDtoYes
operatorstringYesThe individual operator acting, 1-200 characters.
organization_idstring (uuid)Yes
reasonstringYesWhy, 1-500 characters; kept on the ledger row and in the audit log, never shown to the organization.

Responses

StatusDescriptionBody
200—OperatorCreditDto
401Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key).ProblemDetails
404operator access is not configured or the organization is unknownProblemDetails
409insufficient_credit: a claw-back larger than the credit balanceProblemDetails
422Invalid request (invalid_request); field_errors names the fields.ProblemDetails
Request
curl -X POST "$VMYARD_API_URL/v1/operator/billing/credits" \
  -H "X-VMYard-Operator-Token: $X_VMYARD_OPERATOR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "amount_micros": 1,
  "idempotency_key": "string",
  "kind": "grant",
  "operator": "string",
  "organization_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "reason": "string"
}'
Response 200
{
  "credit_balance_micros": 0,
  "outcome": "string"
}