curl --request POST \
--url https://api.gigstack.io/v2/receipts/from-payments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dry_run": true
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({dry_run: true})
};
fetch('https://api.gigstack.io/v2/receipts/from-payments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.gigstack.io/v2/receipts/from-payments"
payload = { "dry_run": True }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"success": true,
"data": {
"start": 1790834400000,
"end": 1793041200000,
"count": 24,
"total": 52310.5,
"with_email": 24,
"truncated": false,
"dry_run": true
},
"message": "Preview of receipts to create",
"timestamp": 1793041200000
}Create receipts for paid payments
Create one pending receipt for every paid payment in a date range that has neither an invoice nor a receipt yet, so each client can invoice it from the self-invoicing portal. The range is on the payment’s creation date and defaults to the current month (Mexico City time); it can span at most one year.
Send dry_run: true first: it only counts (count, total, with_email) and works
on any plan. Creating the receipts is only available on Pricing v3 plans (403 v3_only
on earlier plans), and live v3 teams need the self-invoice portal (self_invoice_portal,
403 feature_not_enabled otherwise). Each call creates at most 200
receipts, oldest first; remaining says how many are left, so call again until it is 0.
Payments that got a receipt meanwhile are skipped, so repeating a call is safe.
The receipt is dated when the payment was made (date), is billed when it is created,
and is valid until the end of the current month. Clients are emailed the link only with
send_email: true. Teams with receipts turned off (avoid_receipts) get 409.
gigstack Connect: create other teams’ receipts with the team parameter.
curl --request POST \
--url https://api.gigstack.io/v2/receipts/from-payments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dry_run": true
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({dry_run: true})
};
fetch('https://api.gigstack.io/v2/receipts/from-payments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.gigstack.io/v2/receipts/from-payments"
payload = { "dry_run": True }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"success": true,
"data": {
"start": 1790834400000,
"end": 1793041200000,
"count": 24,
"total": 52310.5,
"with_email": 24,
"truncated": false,
"dry_run": true
},
"message": "Preview of receipts to create",
"timestamp": 1793041200000
}Authorizations
Authentication Method: HTTP Bearer token.
The runtime requires the literal Bearer prefix — a bare token in the
Authorization header is rejected with 401 unauthorized.
Header Format: Authorization: Bearer YOUR_API_KEY
Your API key is a JWT. Live keys operate on live data (livemode: true);
test keys operate on isolated test data (livemode: false).
Get your key at: app.gigstack.pro/settings?tab=api
Errors: credential failures are answered by the authentication layer with a raw
{ "message": … } body, not the standardized envelope — 401 for a missing, malformed or
expired token, 403 for a revoked key or a plan without API access. See the Unauthorized
and AuthForbidden responses.
Query Parameters
gigstack Connect: Target team ID for multi-team access.
Requires gigstack Connect enabled on your team and shared billing account.
Also requires the multipleIssuerAccounts feature on your plan. Requests targeting a
team other than the one your API key belongs to return 403 without it.
Only API keys can use it: an OAuth access token sent with another team's id is rejected with
403 Team mismatch with OAuth token.
Optional — omit it entirely unless you are acting on another team. It deliberately
carries no example value so generated snippets do not emit ?team=undefined; when the
parameter is absent, the team is derived from your API key.
Example: ?team=team_xyz789
Body
Range start (ms). Default: first day of the current month.
1790834400000
Range end (ms). Default: now.
1793512799000
Only count; create nothing.
true
Email each client the self-invoicing link. Default false.
false
Response
Preview (dry_run).
Standardized success envelope emitted by sendSuccessResponse.
true true
The operation payload.
Server time in epoch milliseconds (Luxon.now().toMillis()).
1767225600000
Human-readable summary. Present only when the handler supplies one.
"Operation completed successfully"