curl --request POST \
--url https://api.gigstack.io/v2/receipts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"client": {
"id": "client_1234567890"
},
"currency": "MXN",
"items": [
{
"id": "service_1234567890",
"quantity": 1
}
],
"periodicity": "month",
"payment_form": "03",
"idempotency_key": "receipt-key-12345",
"metadata": {
"order_id": "ORD-12345"
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
client: {id: 'client_1234567890'},
currency: 'MXN',
items: [{id: 'service_1234567890', quantity: 1}],
periodicity: 'month',
payment_form: '03',
idempotency_key: 'receipt-key-12345',
metadata: {order_id: 'ORD-12345'}
})
};
fetch('https://api.gigstack.io/v2/receipts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.gigstack.io/v2/receipts"
payload = {
"client": { "id": "client_1234567890" },
"currency": "MXN",
"items": [
{
"id": "service_1234567890",
"quantity": 1
}
],
"periodicity": "month",
"payment_form": "03",
"idempotency_key": "receipt-key-12345",
"metadata": { "order_id": "ORD-12345" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)Create receipt
Integration note: A receipt is not yet a stamped CFDI. Repeating a creation idempotency_key returned HTTP 400 resource_conflict in staging. The tested response returned payment_form null despite a request value of 03; verify the fiscal document before issuing it.
Create a new receipt with items and client information. Receipts are pre-invoice documents that can be later stamped as CFDI invoices.
Features:
- Automatic amount calculations with taxes
- Flexible validity periods
- Client auto-creation support
- Metadata support for tracking
- Idempotency support to prevent duplicate receipts
gigstack Connect: Create receipts for other teams using the team parameter.
curl --request POST \
--url https://api.gigstack.io/v2/receipts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"client": {
"id": "client_1234567890"
},
"currency": "MXN",
"items": [
{
"id": "service_1234567890",
"quantity": 1
}
],
"periodicity": "month",
"payment_form": "03",
"idempotency_key": "receipt-key-12345",
"metadata": {
"order_id": "ORD-12345"
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
client: {id: 'client_1234567890'},
currency: 'MXN',
items: [{id: 'service_1234567890', quantity: 1}],
periodicity: 'month',
payment_form: '03',
idempotency_key: 'receipt-key-12345',
metadata: {order_id: 'ORD-12345'}
})
};
fetch('https://api.gigstack.io/v2/receipts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.gigstack.io/v2/receipts"
payload = {
"client": { "id": "client_1234567890" },
"currency": "MXN",
"items": [
{
"id": "service_1234567890",
"quantity": 1
}
],
"periodicity": "month",
"payment_form": "03",
"idempotency_key": "receipt-key-12345",
"metadata": { "order_id": "ORD-12345" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)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
Unknown top-level keys are rejected (400 validation_failed / unexpected_key);
metadata is the one object that accepts arbitrary keys. team, livemode and
owner are reserved and injected by the auth middleware.
Show child attributes
Show child attributes
Currency code (ISO 4217)
"MXN"
Receipt items
Show child attributes
Show child attributes
Exchange rate to use for currency conversion
1
Additional metadata - accepts any custom properties for tracking business data, references, or integration identifiers. All properties are preserved and returned as-is.
Receipt validity period. two_month and two_months are both accepted and
mean the same period (end of the following month).
day, week, two_weeks, month, two_month, two_months, null "month"
Invoice configuration for future stamping. Accepted and validated on this endpoint, but note the create-receipt handler does not currently persist it onto the receipt — it is validated and discarded.
Show child attributes
Show child attributes
SAT payment form code
"01"
Stable key for one business event. A duplicate returns HTTP 400 with error.code resource_conflict, not the existing receipt as a successful response. Reconcile the existing record and retain this key across retries.
"receipt-key-12345"
Whether to send email and WhatsApp notifications for this receipt. Defaults to true.
true
Suppress email and WhatsApp notifications for this receipt. Takes precedence
over send_email — the handler stores ignore_emails ?? (send_email === false).
false
Response
Receipt created successfully. The receipt is stored with status: pending —
no PAC call happens here, so no PAC-related error can be returned by this
operation. Stamping happens later, via POST /v2/receipts/{id}/stamp or the
self-invoicing portal.
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.
"Receipt created successfully"