Skip to content

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:

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/bill
json
{
  "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

StatusWhenBodyRetry
200Receipt stored.JSON, see above
400Payload invalid (schema or business rules).problem details with errors and traceIdno – fix the payload
401Token missing, expired or invalid.empty or plain textrefresh the token, resend once
403Missing scope or API user permission.plain textno
404Unknown storeId (plain text); bill.id not pre-registered (pregeneratedbill-notfound); user not found.plain text or problem detailsno
409A receipt with this bill.id already exists.plain text Bill with id … already existsno – already delivered
503A downstream service failed.emptyyes – exponential backoff, same bill.id
504The receipt could not be stored in time (storage temporarily saturated); the receipt was not stored.emptyyes – exponential backoff, same bill.id
500 / 502Unexpected server error or gateway problem.empty or plain textyes – exponential backoff, same bill.id

POST /v3/bill/url

StatusWhenBodyRetry
200Receipt id registered.JSON with billId and url
400Payload invalid, or the registration failed for a business reason.problem details with traceIdno – fix the payload; if the body reports no validation error, log it and contact anybill
401Token missing, expired or invalid.empty or plain textrefresh the token, resend once
403Missing scope or API user permission.plain textno
404Unknown storeId.plain textno
500 / 502 / 503 / 504Temporary server or gateway problem.empty or plain textyes – 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

StatusWhenBodyRetry
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 traceIdno
401Token missing, expired or invalid.empty or plain textrefresh the token, resend once
403 (printed)Missing scope or API user permission.plain textno
404 (printed)Unknown billId.plain textno
500 / 502 / 503 / 504Temporary server or gateway problem.empty or plain textyes – 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.json

Cancel 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}" }
  • 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.

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.

  1. When no userIdentification.externalId has been provided in the request:
json
// UrlBillResponseDto
{
   "type": "url",
   "url": "url to receipt",
   "billId": "Id of the receipt"
}

  1. When a value in userIdentification.externalId has 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 externalId of 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 exists

Treat 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

FieldTypeDescription
storeIdstring, non-emptyId of the Store that issues the bill in the future

POST /v3/bill

Request body: AddBillDto

Always required

FieldTypeDescription
storeIdstring, 1–36 charsThe id of the store of the vendor in which the transaction was done.
billBillDtoThe definition of a bill based on the version '1.0.0' of the DFKA.
bill.headHeadDtoHead data of the bill.
bill.head.datestring (date-time)Date of invoice.
bill.dataDataDtoBill data.
bill.data.currencystring, exactly 3 charsThis 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.fullAmountInclVatnumber (double)The total gross amount of the receipt. A precision of 2 decimal places is used.
bill.securitySecurityDtoData to secure the receipt via TSE.

Required once the surrounding optional object is sent

ObjectPosition in the request bodyRequired fields
BillDiscountDtobill.data.extension:anybill.discounts[]id, type
DefaultLineDtobill.data.lines[]text, item, extension:anybill
TextLineDtobill.data.lines[]text, extension:anybill
DiscountLineDtobill.data.lines[]text, extension:anybill
KeyValueLineDtobill.data.lines[]type
AnybillDefaultLineExtensionDtobill.data.lines[].extension:anybillsequenceNumber
AnybillTextLineExtensionDtobill.data.lines[].extension:anybillsequenceNumber
AnybillDiscountLineExtensionDtobill.data.lines[].extension:anybillsequenceNumber
AnybillCustomLineExtensionDtobill.data.lines[].extension:anybillsequenceNumber
ItemDtobill.data.lines[].itemnumber, quantity, pricePerUnit
LineVatAmountDtobill.data.lines[].vatAmounts[]percentage, inclVat, exclVat, vat
PaymentTypeInformationDtobill.data.paymentTypes[]name, amount, extension:anybill
AnybillPaymentTypeInformationExtensionDtobill.data.paymentTypes[].extension:anybilltype
DataVatAmountDtobill.data.vatAmounts[]percentage, inclVat, exclVat, vat
SellerDtobill.head.sellername
SellerAddressDtobill.head.seller.addressstreet, postalCode, city
BasicAdditionalReceiptDtobill.misc.additionalReceipts[]type, contentType
VendorAdditionalReceiptDtobill.misc.additionalReceipts[]type, contentType
AfterSalesCouponDtobill.misc.extension:anybill.afterSalesCoupons[]title, codeType, code
FranceSpecificAttributesDtobill.misc.extension:anybill.countrySpecificAttributestype
LoyaltyCouponingInformationDtobill.misc.extension:anybill.couponingInformationtype
CustomSectionDtobill.misc.extension:anybill.customSections[]position, section, data
TseDtobill.security.fiscalizationtype
SwedenFiscalizationDtobill.security.fiscalizationtype
RksvDtobill.security.fiscalizationtype
SecurityInformationDtobill.security.fiscalizationtype
BoiTvaDtobill.security.fiscalizationtype
TBaiDtobill.security.fiscalizationtype
PortugalFiscalizationDtobill.security.fiscalizationtype
AdditionalRksvDataDtobill.security.fiscalization.additionalDatadisplayName, value
AdditionalBoiTvaDataTextDtobill.security.fiscalization.additionalData[]type
AdditionalBoiTvaDataKeyValueDtobill.security.fiscalization.additionalData[]type
SecurityInformationDataDtobill.security.fiscalization.data[]displayed, displayName, value
AdditionalTseDataDtobill.security.fiscalization.extension:anybill.additionalTseDatadisplayName, value

DELETE /v3/bill/

NameLocationTypeDescription
billIdpath parameterstring (uuid)The bills id to be deleted.

POST /v3/bill/{billId}/printed

NameLocationTypeDescription
billIdpath parameterstring (uuid)The bill id where the timestamp to add.

Built 2026-09-16 21:51 CEST from commit d540524