Billing & consent

Confirming a per-project charge.

If your organization is billed per project, creating a new project over the API requires explicitly acknowledging the charge — the API equivalent of the in-app cost-confirmation step.

Who this applies to

Only enterprise per-project organizations, and only when an upload creates a new billable project. It never applies to other plans, and never to saving a new version of an existing project (/versions) or re-uploading identical bytes — those add no billable unit.

Two responses to handle

Error code (402)Meaning & what to do
billing_setup_requiredBilling isn't set up yet (e.g. your first project). A charge can't be approved with no payment configured — set up billing in the PLCs desktop app first, then retry.
billing_acknowledgement_requiredBilling is set up but the charge wasn't acknowledged. The response carries a billing block with the projected cost; disclose it, then resend with acknowledge_billing: true.

The cost block

json
{
  "error": "billing_acknowledgement_required",
  "message": "This project upload will incur a per-project charge that was not acknowledged.",
  "userMessage": "This organization is billed per project. Uploading this project adds a new billable project (about $500.00 USD).",
  "suggestedAction": "Resend the request with \"acknowledge_billing\": true to confirm the charge and create the project.",
  "isRetryable": false,
  "billing": {
    "price_per_project_cents": 50000,
    "currency": "usd",
    "billed_count_after": 3
  },
  "request_id": "req_8f2a1c9d4e5b6a7c8d9e0f12"
}
python
from plcsai import ApiError

try:
    client.ingest_project(file_path="NewLine.L5X")
except ApiError as e:
    if e.error == "billing_setup_required":
        raise SystemExit("Set up billing in the PLCs desktop app first.")
    if e.error == "billing_acknowledgement_required":
        cents = e.billing["price_per_project_cents"]
        print(f"This adds a billable project (~${cents/100:.2f}). Confirming…")
        client.ingest_project(file_path="NewLine.L5X", acknowledge_billing=True)
    else:
        raise
csharp
try
{
    await client.IngestProjectAsync(File.ReadAllBytes("NewLine.L5X"), "NewLine.L5X");
}
catch (PlcsApiException e) when (e.Error == "billing_setup_required")
{
    Console.WriteLine("Set up billing in the PLCs desktop app first.");
}
catch (PlcsApiException e) when (e.Error == "billing_acknowledgement_required")
{
    Console.WriteLine($"This adds a billable project (~${e.Billing!.PricePerProjectCents / 100.0:0.00}). Confirming…");
    await client.IngestProjectAsync(File.ReadAllBytes("NewLine.L5X"), "NewLine.L5X", acknowledgeBilling: true);
}

Acknowledgement is only consulted when a charge actually results. Sending acknowledge_billing: true on an upload that doesn't add a billable project (or for a non-per-project org) is harmless and ignored.