The API reference isn't available right now
This instance couldn't load its API specification. The reference returns as soon as the specification is readable again.
Back to the API reference
No such operation
This instance documents no operation under that identifier. It may have been renamed, or it may belong to a feature this installation hasn't enabled.
Back to the API reference
This reference may be out of date
This instance couldn't reach its API specification on the last attempt, so this page shows the copy fetched before that. Anything added or changed since then is missing here, and the reference updates itself as soon as the specification is readable again. Last fetched 2026-11-12 05:58 UTC.
API reference
/
Merchant Billing
Billing Runs: Creates and runs a billing run for the caller's reseller scope.
POST
/api/billing-runs
deprecated
Requires: MerchantBilling.BillingRuns, MerchantBilling.BillingRuns.Create, merchant scope.
Requires API key scope:
admin
(Administration)
A reseller caller (or an admin acting inside a reseller's context) runs that single reseller;
an admin with no reseller context fans out across every reseller with billable merchants. Set
`ResellerId` to run one named reseller instead: the caller's own or one beneath it (an
admin may name any). Set `IsDryRun` on the input for a preview that calculates charges
without generating invoices.
Signed in, you can send this request to your own sandbox merchant from the console
and read the answer.
Sign in to try it .
On this page
Example request
Every block below sends the same request. Replace {{BASE_URL}} with the address of the API you are calling and {{API_KEY}} with your own key.
The request body is a CreateBillingRunInput. See the Request body section below for its fields.
Code sample language >_
cURL PS
PowerShell TS
TypeScript C#
C# Py
Python
Copythe install command for cURL
Copied
Copy failed
cURL CopycURL
Copied
Copy failed
curl -X POST "{{BASE_URL}}/api/billing-runs" \
-H "api-key: {{API_KEY}}" \
-H "Content-Type: application/json" \
-d '{
"periodKey": ""
}'
Copythe install command for PowerShell
Copied
Copy failed
PowerShell CopyPowerShell
Copied
Copy failed
$headers = @{
'api-key' = '{{API_KEY}}'
}
$body = @'
{
"periodKey": ""
}
'@
$response = Invoke-RestMethod -Method POST -Uri '{{BASE_URL}}/api/billing-runs' `
-Headers $headers -ContentType 'application/json' -Body $bodynpm install @winkpg/winkpg-api
Copythe install command for TypeScript (SDK)
Copied
Copy failed
TypeScript (SDK) CopyTypeScript (SDK)
Copied
Copy failed
import { Configuration, MerchantBillingApi } from '@winkpg/winkpg-api';
const api = new MerchantBillingApi(new Configuration({
basePath: '{{BASE_URL}}',
apiKey: '{{API_KEY}}',
}));
const { data } = await api.billingRunCreateAndRun({
"periodKey": ""
});
Copythe install command for TypeScript (raw HTTP)
Copied
Copy failed
TypeScript (raw HTTP) CopyTypeScript (raw HTTP)
Copied
Copy failed
const response = await fetch('{{BASE_URL}}/api/billing-runs', {
method: 'POST',
headers: {
"api-key": "{{API_KEY}}",
"Content-Type": "application/json",
},
body: JSON.stringify({
"periodKey": ""
}),
});
const data = await response.json();dotnet add package WinkPg.Api.Client
Copythe install command for C# (SDK)
Copied
Copy failed
C# (SDK) CopyC# (SDK)
Copied
Copy failed
using WinkPg.Api.Client.Api;
using WinkPg.Api.Client.Client;
using System.Text.Json;
var config = new Configuration { BasePath = "{{BASE_URL}}" };
config.AddApiKey("api-key", "{{API_KEY}}");
var api = new MerchantBillingApi(config);
var body = JsonSerializer.Deserialize<CreateBillingRunInput>("""
{
"periodKey": ""
}
""");
var result = await api.BillingRunCreateAndRunAsync(body);
Copythe install command for C# (raw HTTP)
Copied
Copy failed
C# (raw HTTP) CopyC# (raw HTTP)
Copied
Copy failed
using System.Text;
using var http = new HttpClient { BaseAddress = new Uri("{{BASE_URL}}") };
var request = new HttpRequestMessage(new HttpMethod("POST"), "/api/billing-runs");
request.Headers.Add("api-key", "{{API_KEY}}");
request.Content = new StringContent("""
{
"periodKey": ""
}
""", Encoding.UTF8, "application/json");
var response = await http.SendAsync(request);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();pip install winkpg-api
Copythe install command for Python (SDK)
Copied
Copy failed
Python (SDK) CopyPython (SDK)
Copied
Copy failed
import winkpg_api
configuration = winkpg_api.Configuration(host="{{BASE_URL}}")
configuration.api_key["ApiKey"] = "{{API_KEY}}"
with winkpg_api.ApiClient(configuration) as client:
api = winkpg_api.MerchantBillingApi(client)
body = winkpg_api.CreateBillingRunInput.from_dict({
"periodKey": ""
})
result = api.billing_run_create_and_run(body)pip install requests
Copythe install command for Python (raw HTTP)
Copied
Copy failed
Python (raw HTTP) CopyPython (raw HTTP)
Copied
Copy failed
import requests
headers = {
"api-key": "{{API_KEY}}",
"Content-Type": "application/json",
}
body = {
"periodKey": ""
}
response = requests.request(
"POST",
"{{BASE_URL}}/api/billing-runs",
headers=headers,
json=body,
)
response.raise_for_status()
data = response.json()
Parameters
Name
In
Type
Description
suppressNulls
required
query
boolean
If true, omit properties with null values.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
Request body
application/json
, required
Field
Type
Description
periodKey
required
string
Billing period key in yyyyMM format (e.g., "202602" for February 2026).
nullable min length 0 max length 10
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
isDryRun
required
boolean
When true, calculates charges without generating invoices (preview mode).
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
resellerId
required
string (uuid)
Optional reseller to run billing for. Omit it to run for the caller's own reseller (or, for an
admin with no reseller selected, to bill every reseller). When set, the run bills that one
reseller's merchants; a reseller caller may name their own reseller or any reseller beneath it,
and an admin may name any reseller. A reseller outside the caller's scope is reported as not
found. Not accepted by the all-resellers trigger.
Conditional: When ResellerId is not null.
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
This request body has no documented fields.
Responses
Response status
200
OK
The run was created (or the fan-out was started).
Body:
BillingRunBatchResultDto
BillingRunBatchResultDto
Each item has these fields.
Field
Type
Description
periodKey
required
string
Billing period key (yyyyMM) the batch was run for.
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
isDryRun
required
boolean
True when charges were previewed without generating invoices/charges.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
wasFanOut
required
boolean
True when this was an admin cross-reseller fan-out; false for a single-reseller run.
Drives whether the UI shows the multi-reseller summary or the single-run message.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
isAsyncStarted
required
boolean
True when the fan-out was started as a Durable background process rather than
run inline: the per-reseller counts in this result are not yet populated. Callers track
progress via `BillingRunBatchStatusDto` (`batchId`).
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
batchId
required
string (uuid)
The background batch id when `isAsyncStarted` is true; otherwise null.
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
resellersConsidered
required
integer (int32)
Number of resellers evaluated (the full set considered for the run).
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
resellersRun
required
integer (int32)
Number of resellers for which a billing run actually executed.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
resellersSkipped
required
integer (int32)
Number of resellers skipped without running: no billable merchants for the period,
or a completed run already exists / is in progress for the period.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
resellersFailed
required
integer (int32)
Number of resellers whose run failed.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
totalMerchantsBilled
required
integer (int32)
Total merchants successfully billed across every reseller run in the batch.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
totalMerchantsFailed
required
integer (int32)
Total merchants that failed within the executed reseller runs. A run can complete at the
reseller level while individual merchants fail; this surfaces those so the toast severity
reflects them (a fan-out with merchant failures is not a clean success).
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
outcomes
required
array of BillingRunResellerOutcomeDto
array of BillingRunResellerOutcomeDto
Per-reseller outcomes.
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
Fields of each BillingRunResellerOutcomeDto:
Field
Type
Description
resellerId
required
string (uuid)
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
resellerName
required
string
Display name of the reseller, when resolvable (admin fan-out only).
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
billingRunId
required
string (uuid)
The created run's id, when a run executed (null for skipped resellers).
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
outcome
required
BillingRunResellerOutcome
BillingRunResellerOutcome
Classifies how a single reseller fared within an admin billing-run batch. Lives in
Domain.Shared so the Domain aggregate (`MerchantBillingRunBatch`'s embedded
outcome) and the Application.Contracts DTOs can both reference it without a layer violation.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
Completed
A run executed for the reseller (may include per-merchant failures within it). SkippedNoBillableMerchants
No merchants were assigned to a price plan for the period: no run was created. SkippedAlreadyRun
A completed (non-dry) run already exists for this reseller and period. SkippedRunInProgress
A run is already in progress for this reseller. Failed
The reseller's run failed before completion (or failed to enqueue). Scheduled
The reseller's run was accepted and queued as a background job. Merchants are billed asynchronously; the run's final status (Completed, PartiallyCompleted or Failed) appears on the run once processing finishes. An all-resellers batch reports progress through the batch status instead. SkippedMerchantBillingDisabled
The reseller has the "Merchant Billing" master switch (ResellerFeatures.MerchantBilling) turned off, so no run was created and no invoices were generated for its merchants.
successCount
required
integer (int32)
Merchants successfully billed in this reseller's run.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
failureCount
required
integer (int32)
Merchants that failed in this reseller's run.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
totalBilledAmount
required
number (double)
Total amount billed in this reseller's run.
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
This body has no documented fields.
This response has no documented body fields.
429
Too Many Requests
The request was refused because a rate limit was exceeded, or because something a later retry can clear stopped it. A rate limit refusal carries an `application/problem+json` body: wait at least the interval `Retry-After` names before retrying, then back off. Limits are tuned per deployment, so read the allowance from the response headers rather than assuming a fixed ceiling. Any other refusal carries the standard error envelope as `application/json`, and its `error.code` names the cause.
Body:
RemoteServiceErrorResponse
RemoteServiceErrorResponse
Each item has these fields.
Field
Type
Description
error
required
RemoteServiceErrorInfo
RemoteServiceErrorInfo
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
This response has no documented body fields.
Errors
400 401 403 404 500 501 default
400
Bad Request
Bad request. The request was malformed or failed validation. When validation rejected it, `error.validationErrors` names each member at fault and why. 401
Unauthorized
Unauthorized. The request carried no API key or signed-in session, or the key it carried is invalid, revoked or expired. 403
Forbidden
Forbidden. The API key lacks the scope this operation needs, the signed-in user lacks the permission, or a business rule refused the request. The error code in the body names the reason. 404
Not Found
The named reseller does not exist or is outside the caller's reseller scope. 500
Internal Server Error
Internal server error. The platform failed unexpectedly while handling the request. If it keeps failing, contact support and quote the correlation id, which the response carries in the `X-Correlation-Id` header and as `error.data.correlationId`. 501
Not Implemented
Not implemented. The operation is declared but has no implementation on this deployment, so no request to it can succeed. Retrying does not help. default
The request failed. The body carries the standard error envelope: a machine-readable `error.code`, a human-readable `error.message`, and `error.validationErrors` when the failure was a validation rejection. The error reference lists the values `error.code` can take. The request failed. The body carries the standard error envelope: a machine-readable `error.code`, a human-readable `error.message`, and `error.validationErrors` when the failure was a validation rejection. The error reference lists the values `error.code` can take.
Body:
RemoteServiceErrorResponse
RemoteServiceErrorResponse
Each item has these fields.
Field
Type
Description
error
required
RemoteServiceErrorInfo
RemoteServiceErrorInfo
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
Fields of RemoteServiceErrorInfo:
Field
Type
Description
code
required
string
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
message
required
string
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
details
required
string
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
data
required
object
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
validationErrors
required
array of RemoteServiceValidationErrorInfo
array of RemoteServiceValidationErrorInfo
nullable
Values:
Values combine: send one or more member names separated by a comma and a space, or the integer sum of their values. Responses carry the names.
This body has no documented fields.
This response has no documented body fields.
Next steps