Appearance
Bill Endpoints
This page covers the routes that send receipts to anybill and how a receipt is linked to a consumer. The structure of the receipt payload itself is described in the Bill Data Model, and worked examples for discounts, returns and custom sections in Bill Examples.
Endpoints
The receipt controller offers four routes:
- POST
/v3/bill/url: Pre-register a receipt ID and get the receipt URL (QR code) in advance. - POST
/v3/bill: Send receipt to anybill. - DELETE
/v3/bill/{billId}: Cancel a receipt based on the billId.- DELETE Staging Swagger | Production Swagger
- POST
/v3/bill/{billId}/printed: Adds a printed timestamp to the receipt.
Detailed Endpoint Description
Staging Environment: SwaggerUI
Production Environment: SwaggerUI
Request
The store ID must be sent in the body of both POST /v3/bill/url and POST /v3/bill. POST /v3/bill/url optionally accepts a buyerInformation object; POST /v3/bill takes the receipt itself in bill (see Bill Data Model).
POST /v3/billjson
{
"storeId": "3QT1su7Wtl",
"userIdentification": { "externalId": "optional, see below" },
"bill": { ... } // see Bill Data Model / Swagger
}Response
Both routes return a json object with the receipt id and, unless the receipt was assigned to a known user, the url from which the QR code can be generated.
json
{
"type": "url",
"url": "url to receipt",
"billId": "Id of the receipt"
}Status codes
The Retry column is the behaviour a POS system has to implement for each code; the common rules (backoff, attempts, idempotency, token refresh on 401) are described in the Retry Policy Guidelines. None of the bill endpoints returns 429.
POST /v3/bill
| Status | When | Body | Retry |
|---|---|---|---|
| 200 | Receipt stored. | JSON, see above | – |
| 400 | Payload invalid (schema or business rules). | problem details with errors and traceId | no – fix the payload |
| 401 | Token missing, expired or invalid. | empty or plain text | refresh the token, resend once |
| 403 | Missing scope or API user permission. | plain text | no |
| 404 | Unknown storeId (plain text); bill.id not pre-registered (pregeneratedbill-notfound); user not found. | plain text or problem details | no |
| 409 | A receipt with this bill.id already exists. | plain text Bill with id … already exists | no – already delivered |
| 503 | A downstream service failed. | empty | yes – exponential backoff, same bill.id |
| 504 | The receipt could not be stored in time (storage temporarily saturated); the receipt was not stored. | empty | yes – exponential backoff, same bill.id |
| 500 / 502 | Unexpected server error or gateway problem. | empty or plain text | yes – exponential backoff, same bill.id |
POST /v3/bill/url
| Status | When | Body | Retry |
|---|---|---|---|
| 200 | Receipt id registered. | JSON with billId and url | – |
| 400 | Payload invalid, or the registration failed for a business reason. | problem details with traceId | no – fix the payload; if the body reports no validation error, log it and contact anybill |
| 401 | Token missing, expired or invalid. | empty or plain text | refresh the token, resend once |
| 403 | Missing scope or API user permission. | plain text | no |
| 404 | Unknown storeId. | plain text | no |
| 500 / 502 / 503 / 504 | Temporary server or gateway problem. | empty or plain text | yes – exponential backoff; a second registration for the same sale is harmless as long as the POS keeps only the billId it finally sends |
DELETE /v3/bill/{billId} and POST /v3/bill/{billId}/printed
| Status | When | Body | Retry |
|---|---|---|---|
204 (DELETE) / 200 (printed) | Accepted. DELETE always answers 204 – an unknown billId is not reported. | empty / billId | – |
400 (printed) | The receipt could not be marked as printed (business rule). | problem details with traceId | no |
| 401 | Token missing, expired or invalid. | empty or plain text | refresh the token, resend once |
403 (printed) | Missing scope or API user permission. | plain text | no |
404 (printed) | Unknown billId. | plain text | no |
| 500 / 502 / 503 / 504 | Temporary server or gateway problem. | empty or plain text | yes – exponential backoff; both operations are idempotent |
curl examples
All routes take the access token from Authentication as a Bearer token. The examples use the Staging base URL https://vendor.stg.anybill.de/api; all routes live below the /api prefix.
Pre-register a receipt ID (for a QR code before payment, or to make the later POST /v3/bill idempotent):
bash
curl -X POST 'https://vendor.stg.anybill.de/api/v3/bill/url' \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{ "storeId": "3QT1su7Wtl" }'Send a receipt whose payload is stored in receipt.json:
bash
curl -X POST 'https://vendor.stg.anybill.de/api/v3/bill' \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d @receipt.jsonCancel a receipt (204 when the cancellation was accepted) and record a later paper print:
bash
curl -X DELETE 'https://vendor.stg.anybill.de/api/v3/bill/<billId>' \
-H 'Authorization: Bearer <access_token>'
curl -X POST 'https://vendor.stg.anybill.de/api/v3/bill/<billId>/printed' \
-H 'Authorization: Bearer <access_token>'The POST /v3/bill-route can be used to add following types of receipts.
- Anonymous Receipts:
- This is the case if the POS not provide a user identifier as a value in
userIdentification.externalId- e.g. via QR code scan of a loyalty card of the consumer.
Example:json{ "url": "https://getmy.anybill.de/{billId}" }
- This is the case if the POS not provide a user identifier as a value in
- User Receipts:
- This is the case if the POS provides a value in
userIdentification.externalId, e.g. the loyalty/crm identifier scanned at the POS. Here, anybill can use this information to e.g. assign the receipt automatically to the consumer's app account, use it for analytics, insights and actions in Purchase Intelligence or many other use cases.
- This is the case if the POS provides a value in
If the user identification object or all its property are null, the receipt will be treated as anonymous.
Response objects
The /v3/bill endpoint returns different response objects.
- When no
userIdentification.externalIdhas been provided in the request:
json
// UrlBillResponseDto
{
"type": "url",
"url": "url to receipt",
"billId": "Id of the receipt"
}- When a value in
userIdentification.externalIdhas been provided in the request and the receipt was matched with an external user (e.g. receipt was assigned to a user account to make it visible in the merchant's app) - without requiring a QR code.:
json
// ExternalIdResponseDto
{
"type": "externalId",
"isAssigned": true,
"billId": "Id of the receipt"
}💡 isAssigned will always be true if type is externalId. If userIdentification.externalId has been defined, and no match could be made, the response is of type url.
Two further type values exist for legacy assignment paths and have the same shape as ExternalIdResponseDto (billId, isAssigned: true): userId (receipt matched via the deprecated userIdentification.userId) and bankCard (receipt matched via a bank card registered by the consumer). New integrations only need to handle url and externalId, but should treat any response with isAssigned: true as "no QR code required".
User identification
If a receipt with a link to a known consumer should be added, the property userIdentification.externalId must be set with the identifier value.
- The
externalIdof the consumer is an identifier from a marchant's system like CRM (customer number), Loyalty. The maximum length is 256 characters.
Transparent user creation via externalId
Historically, anybill required merchants to first create an anybill user via the Partner Platform API, in order to link an externalId-Identifier to it later.
After popular demand, this requirement has been removed:
If the provided userIdentification.externalId is not yet known to anybill, anybill internally creates an anonymous anybill user automatically and the receipt is assigned to it.
No pre-registration or creation of an internal anybill user is required anymore.
On subsequent receipts with the same userIdentification.externalId value, the existing user is reused.
The same userIdentification.externalId can later be passed to the Partner Platform API token endpoint to obtain an SDK token for that user.
WARNING
The "Transparent user creation via externalId" - flow has to be manually enabled per merchant on the anybill side. If it is relevant for your integration, please contact dev@anybill.de or your anybill contact person.
Deprecated useridentification fields
The previously available userIdentification.userId (anybill user id) and userIdentification.loyaltyCardBarcode fields are deprecated and will be removed in a future revision. Use userIdentification.externalId for all new integrations.
Self-generated Receipt Id
The Vendor API optionally offers the possibility that the POS system generates a Receipt ID (UUID) independently, prior to sending the receipt data.
WARNING
The "Self-generated Receipt Id" - feature has to be manually enabled per merchant on the anybill side. If it is relevant for your integration, please contact dev@anybill.de or your anybill contact person.
If a self-generated Receipt Id already exists
If the self-generated receipt UUID already exists in the anybill system, the request is rejected with HTTP 409 Conflict. The body is a plain string, not a problem-details object:
Bill with id 5e952ea6-167d-4001-95d9-a759204c2943 already existsTreat a 409 as "this receipt has already been stored" and do not retry it.
If the feature is not enabled
If bill.id is set but the id was neither pre-registered via POST /v3/bill/url nor is the feature enabled for the merchant, the API answers with HTTP 404 and the problem details { "type": "pregeneratedbill-notfound", "title": "PreGeneratedBill could not be found.", "status": 404 }.
Cancelling a receipt
A receipt is cancelled with DELETE /v3/bill/{billId}. The billId is part of the request path.
TIP
The response returns status code 204 as soon as the cancellation has been accepted. The cancellation itself is processed asynchronously, so an unknown billId is not reported back to the caller; make sure to send the id that was returned by POST /v3/bill or POST /v3/bill/url.
Required Fields
These fields are validated against the OpenAPI schema; the business rules described in the Bill Data Model apply on top of them. Fields listed as required once the surrounding object is sent belong to an optional part of the payload — omitting that part entirely is fine, including it makes the listed fields mandatory.
For bill.security.fiscalization the OpenAPI schema only marks type as required. The fields that are actually mandatory depend on the fiscalization type and are validated server-side; see Fiscalization.
Generated from the production OpenAPI specification (API version 3.0) on 3 September 2026.
POST /v3/bill/url
Request body: RegisterBillIdDto
Always required
| Field | Type | Description |
|---|---|---|
storeId | string, non-empty | Id of the Store that issues the bill in the future |
POST /v3/bill
Request body: AddBillDto
Always required
| Field | Type | Description |
|---|---|---|
storeId | string, 1–36 chars | The id of the store of the vendor in which the transaction was done. |
bill | BillDto | The definition of a bill based on the version '1.0.0' of the DFKA. |
bill.head | HeadDto | Head data of the bill. |
bill.head.date | string (date-time) | Date of invoice. |
bill.data | DataDto | Bill data. |
bill.data.currency | string, exactly 3 chars | This field defines the currency to be used for all document data if no other currency is explicitly specified. Must be a valid ISO 4217 currency code… |
bill.data.fullAmountInclVat | number (double) | The total gross amount of the receipt. A precision of 2 decimal places is used. |
bill.security | SecurityDto | Data to secure the receipt via TSE. |
Required once the surrounding optional object is sent
| Object | Position in the request body | Required fields |
|---|---|---|
BillDiscountDto | bill.data.extension:anybill.discounts[] | id, type |
DefaultLineDto | bill.data.lines[] | text, item, extension:anybill |
TextLineDto | bill.data.lines[] | text, extension:anybill |
DiscountLineDto | bill.data.lines[] | text, extension:anybill |
KeyValueLineDto | bill.data.lines[] | type |
AnybillDefaultLineExtensionDto | bill.data.lines[].extension:anybill | sequenceNumber |
AnybillTextLineExtensionDto | bill.data.lines[].extension:anybill | sequenceNumber |
AnybillDiscountLineExtensionDto | bill.data.lines[].extension:anybill | sequenceNumber |
AnybillCustomLineExtensionDto | bill.data.lines[].extension:anybill | sequenceNumber |
ItemDto | bill.data.lines[].item | number, quantity, pricePerUnit |
LineVatAmountDto | bill.data.lines[].vatAmounts[] | percentage, inclVat, exclVat, vat |
PaymentTypeInformationDto | bill.data.paymentTypes[] | name, amount, extension:anybill |
AnybillPaymentTypeInformationExtensionDto | bill.data.paymentTypes[].extension:anybill | type |
DataVatAmountDto | bill.data.vatAmounts[] | percentage, inclVat, exclVat, vat |
SellerDto | bill.head.seller | name |
SellerAddressDto | bill.head.seller.address | street, postalCode, city |
BasicAdditionalReceiptDto | bill.misc.additionalReceipts[] | type, contentType |
VendorAdditionalReceiptDto | bill.misc.additionalReceipts[] | type, contentType |
AfterSalesCouponDto | bill.misc.extension:anybill.afterSalesCoupons[] | title, codeType, code |
FranceSpecificAttributesDto | bill.misc.extension:anybill.countrySpecificAttributes | type |
LoyaltyCouponingInformationDto | bill.misc.extension:anybill.couponingInformation | type |
CustomSectionDto | bill.misc.extension:anybill.customSections[] | position, section, data |
TseDto | bill.security.fiscalization | type |
SwedenFiscalizationDto | bill.security.fiscalization | type |
RksvDto | bill.security.fiscalization | type |
SecurityInformationDto | bill.security.fiscalization | type |
BoiTvaDto | bill.security.fiscalization | type |
TBaiDto | bill.security.fiscalization | type |
PortugalFiscalizationDto | bill.security.fiscalization | type |
AdditionalRksvDataDto | bill.security.fiscalization.additionalData | displayName, value |
AdditionalBoiTvaDataTextDto | bill.security.fiscalization.additionalData[] | type |
AdditionalBoiTvaDataKeyValueDto | bill.security.fiscalization.additionalData[] | type |
SecurityInformationDataDto | bill.security.fiscalization.data[] | displayed, displayName, value |
AdditionalTseDataDto | bill.security.fiscalization.extension:anybill.additionalTseData | displayName, value |
DELETE /v3/bill/
| Name | Location | Type | Description |
|---|---|---|---|
billId | path parameter | string (uuid) | The bills id to be deleted. |
POST /v3/bill/{billId}/printed
| Name | Location | Type | Description |
|---|---|---|---|
billId | path parameter | string (uuid) | The bill id where the timestamp to add. |