BillingCreditHoldCreateRequest billing.credit-hold-create-request@1

Generated at from openvibe-contracts v0.419.0 and openvibe-sdk v0.161.0.

Version
1.0.0
Owner
billing
Visibility
internal
Status
active
Compatibility
backward
Schema
https://openvibe.network/contracts/billing/credit-hold-create-request.v1.json

billing.credit-hold-create-request@1: body of POST /internal/credits/holds. Reserves inference credit up to max_nano_usd against a Balance account, priced at the given immutable rate version. With project_id the hold spends that project's Balance; without it the hold is personal and spends the subject's own Balance (D12). An app subject always names its project.

Fields

FieldTypeRequiredDescriptionConstraints
idempotency_keystringyes
  • pattern ^[A-Za-z0-9._:-]{8,128}$
subjectidentity.subject-refyes
project_idstringThe project whose Balance the hold spends. Optional: without it the hold is personal, on the subject's own Balance. Required when the subject is an app.
  • pattern ^prj_[0-9A-HJKMNP-TV-Z]{26}$
credential_idstring | null
  • pattern ^cred_[0-9A-HJKMNP-TV-Z]{26}$
max_nano_usdhttps://openvibe.network/contracts/billing/credit-hold-create-request.v1.json#/$defs/money-nano-usdyes
rate_versionstringyes
request_fingerprintstringyes
  • maxLength 1024
servicestringWhich metered service spends the credit (D9): ai, run, ... Defaults to ai.
  • pattern ^[a-z][a-z0-9-]{0,39}$
sandboxbooleanD10. A sandbox caller's hold draws on that person's sandbox credit for the project (account kind usd_credit_sandbox, owner subject:project), never on real Credits, and a real hold never draws on sandbox credit. Sandbox grants (billing.credit-sandbox-grant-request@1) land in that sandbox account. Optional; defaults to false.
  • default false

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: minimal
{
  "idempotency_key": "hold-key-001",
  "subject": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "max_nano_usd": "100000000",
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-001"
}
Valid: personal-hold
{
  "idempotency_key": "hold-key-personal-001",
  "subject": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "max_nano_usd": "100000000",
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-personal-001",
  "service": "ai"
}
Valid: sandbox
{
  "idempotency_key": "hold-key-sandbox-001",
  "subject": {
    "type": "app",
    "id": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "max_nano_usd": "50000000",
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-sandbox-001",
  "service": "ai",
  "sandbox": true
}
Valid: with-credential
{
  "idempotency_key": "hold-key-002",
  "subject": {
    "type": "app",
    "id": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "credential_id": "cred_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "max_nano_usd": "50000000",
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-002"
}
Rejected: app-without-project
{
  "idempotency_key": "hold-key-app-001",
  "subject": {
    "type": "app",
    "id": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "max_nano_usd": "50000000",
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-app-001"
}
Rejected: bad-subject
{
  "idempotency_key": "hold-key-001",
  "subject": {
    "type": "person",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "max_nano_usd": "100000000",
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-001"
}
Rejected: missing-key
{
  "subject": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "max_nano_usd": "100000000",
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-001"
}
Rejected: money-number
{
  "idempotency_key": "hold-key-001",
  "subject": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "max_nano_usd": 100000000,
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-001"
}
Rejected: sandbox-string
{
  "idempotency_key": "hold-key-sandbox-002",
  "subject": {
    "type": "app",
    "id": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "max_nano_usd": "50000000",
  "rate_version": "rr-2026-11-03-001",
  "request_fingerprint": "fp-chat-sandbox-002",
  "service": "ai",
  "sandbox": "yes"
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('billing.credit-hold-create-request@1', value);   // { valid, errors: [{ path, message }] }