Skip to main content

📄 Guide

Velocity rules are standalone objects: owned by a company, bound many-to-many to cards or employees, with the strictest value winning per dimension. This page walks “create → bind → query quota → adjust”; the concepts are in Limits and statements.

Creating a rule

POST /open-api-corp/velocity/v1/create-rule — send ruleRef (idempotency key: the same company + ruleRef on retry returns the first result), organizationId, ruleName, and at least one of the five control groups (none at all returns DAPI_PARAM_INVALID):
“Unlimited” is expressed by omitting the field — never send 0 or a negative number (VELOCITY_LIMIT_VALUE_INVALID). Amount limits match on the settlement currency, while currencyControl judges the original purchase currency — two different axes.
A new rule is always ACTIVE, but constrains nothing until it is bound to a card or employee. The response returns ruleId, ruleVersion (optimistic lock), bindingCount and more.

Binding and unbinding

Bind: POST /open-api-corp/velocity/v1/bind — one request addresses one rule (top-level ruleId) and a batch of subjects in targets[] (subjectType CARD / CUSTOMER + subjectId). Rule-level problems (missing / not ACTIVE) reject the whole batch; subject-level problems are item-independent with partial success: the response splits into successTargets and failTargets, with per-item reasons such as SUBJECT_INVALID / CARD_RULE_DUPLICATE / CARD_RULE_CURRENCY_NOT_MATCH. Rules can also be bound at issue time through ruleIds. A single card or employee carries at most 5 rules. Unbind: POST /open-api-corp/velocity/v1/unbind — batch, partial success as above; a subject not bound to the rule fails per-item with VELOCITY_BINDING_NOT_FOUND. Query targets: list-rule-targets (objects bound to a rule) and list-target-rules (rules constraining a card / employee; ACTIVE only by default).

Querying effective quota

GET /open-api-corp/velocity/v1/query-quota — the merged effective limits and current usage for a card / employee, from which you compute the remainder. Key points:
  • Each quota node returns limitAmount / usedAmount / remainingAmount / utilizationRate / periodKey / sourceRuleIdsourceRuleId names the rule the strictest value came from; limit=null means the dimension is uncapped (usedAmount still accumulates).
  • perTransaction carries only limitAmount and sourceRuleId — per-transaction limits do not accumulate.
  • Each currency group carries an effective flag: false + NOT_CARD_SETTLEMENT_CURRENCY means the currency is not among the card’s settlement currencies and does not apply.
  • cashAdvance.allowed is the merged switch: false if any rule says false, with sourceRuleId naming which one.
  • appliedRules lists the rules in the merge (always ACTIVE — INACTIVE rules never participate).

Adjusting rules

Update: POST /open-api-corp/velocity/v1/update-rulefull-replacement semantics: any dimension or control group absent from the request is deleted; ruleVersion must be echoed back, and a mismatch returns VELOCITY_RULE_VERSION_CONFLICT (concurrent modification — re-query and retry). Changes take effect immediately on bound objects. Enable / disable: POST /open-api-corp/velocity/v1/change-rule-status — toggles ACTIVEINACTIVE (also versioned). An INACTIVE rule takes no part in checks but keeps its targets; the response echoes bindingCount — before disabling, warn the customer that the rule currently constrains N objects. Detail / list: query-rule (full configuration) and list-rules (paginated summaries, filterable by status).

Next steps