{"openapi":"3.0.1","info":{"title":"payware API","description":"payware Payment Engine REST API - Comprehensive API for managing transactions, products, and payment processing","contact":{"name":"payware Support","url":"https://payware.eu","email":"support@payware.eu"},"license":{"name":"Proprietary","url":"https://legal.payware.eu/en/api-agreement"},"version":"v1.0"},"servers":[{"url":"https://api.payware.eu","description":"Production Server"},{"url":"https://sandbox.payware.eu","description":"Sandbox Server"},{"url":"http://localhost:8080","description":"Local Development Server"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Transactions","description":"Transaction management API for creating, processing, and managing payment transactions"},{"name":"POI","description":"Point of Interaction API for managing physical payment points with dynamic pricing"},{"name":"Products","description":"Product management API for creating, updating, and managing products and their payment links"},{"name":"Products / Schedules","description":"API for managing product price schedules and time-constrained pricing"},{"name":"Products / Audios","description":"API for managing product audio soundbites for payment initiation over audio channels"},{"name":"Reports","description":"Report generation and data retrieval API for business intelligence and analytics"},{"name":"OAuth2","description":"OAuth2 token management for ISV merchant delegation"},{"name":"ISV Invitations","description":"Create and manage merchant invitations. Invitations generate a unique link that the ISV distributes to merchants through their own channels. No emails are sent by the API - the ISV is responsible for delivering the invitation link."},{"name":"Shops","description":"Shop API for retrieving shop information"},{"name":"Logs","description":"Tenant log access API"},{"name":"ISV Reference Data","description":"Reference data for merchant registration forms"},{"name":"Campaigns","description":"Group a product's placements into campaigns and read their results"},{"name":"Products / Placements","description":"Distribute a product through placements and read their results"},{"name":"Products / Placements / Airings","description":"Schedule when a placement is on air"},{"name":"ISV","description":"General ISV endpoints for consent configuration and reference data"}],"paths":{"/api/products/{productId}/placements/{placementId}/airings/{ruleId}":{"get":{"tags":["Products / Placements / Airings"],"summary":"Get an airing rule","operationId":"getAiring","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}},{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"The rule","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AiringRuleDTO"}}}},"404":{"description":"Airing rule not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"put":{"tags":["Products / Placements / Airings"],"summary":"Replace an airing rule","operationId":"updateAiring","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}},{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiringRuleRequest"}}},"required":true},"responses":{"200":{"description":"Updated","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AiringRuleDTO"}}}},"400":{"description":"Invalid rule or window, or outside the product window","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Airing rule not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Products / Placements / Airings"],"summary":"Delete an airing rule","operationId":"deleteAiring","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}},{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"204":{"description":"Deleted"},"404":{"description":"Airing rule not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/placements/{placementId}/airings":{"get":{"tags":["Products / Placements / Airings"],"summary":"List a placement's airing rules","operationId":"listAirings","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Rules","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiringRuleDTO"}}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"put":{"tags":["Products / Placements / Airings"],"summary":"Replace all airing rules","description":"All or nothing. When any rule is refused, nothing is saved and the 400 lists each refused rule by its index","operationId":"replaceAirings","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiringRuleRequest"}}}},"required":true},"responses":{"200":{"description":"The saved rules","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiringRuleDTO"}}}}},"400":{"description":"Refused rows","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AiringBatchErrorDTO"}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["Products / Placements / Airings"],"summary":"Add an airing rule","description":"Up to 100 rules per placement and 24 windows per rule. warnings lists other soundbite placements of the product airing at the same time","operationId":"createAiring","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiringRuleRequest"}}},"required":true},"responses":{"400":{"description":"Invalid rule or window, outside the product window, or a limit is reached","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AiringRuleDTO"}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/placements/{placementId}":{"get":{"tags":["Products / Placements"],"summary":"Get a placement","operationId":"getPlacement","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","description":"Placement id","required":true,"schema":{"type":"string"},"example":"pl7e4rCToG"}],"responses":{"200":{"description":"The placement","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementDTO"}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"put":{"tags":["Products / Placements"],"summary":"Replace a placement's details","description":"Every field is replaced; a missing active keeps the current value","operationId":"updatePlacement","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementRequest"}}},"required":true},"responses":{"400":{"description":"Invalid placement","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Updated","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementDTO"}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Products / Placements"],"summary":"Delete a placement","description":"Its id is never reused and its short link is retired. Its printed codes stop resolving","operationId":"deletePlacement","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/campaigns/{campaignId}":{"get":{"tags":["Campaigns"],"summary":"Get a campaign","operationId":"getCampaign","parameters":[{"name":"campaignId","in":"path","description":"Campaign id","required":true,"schema":{"type":"string"},"example":"cp7e4rCToG"}],"responses":{"200":{"description":"The campaign","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CampaignDTO"}}}},"404":{"description":"Campaign not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"put":{"tags":["Campaigns"],"summary":"Replace a campaign's details","description":"Replaces name, dates and external reference; a missing status keeps the current one","operationId":"updateCampaign","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRequest"}}},"required":true},"responses":{"400":{"description":"Invalid campaign","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Updated","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CampaignDTO"}}}},"404":{"description":"Campaign not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Campaigns"],"summary":"Delete a campaign","description":"Its placements stay and are detached from it","operationId":"deleteCampaign","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"404":{"description":"Campaign not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/poi/{poiId}/price":{"put":{"tags":["POI"],"summary":"Set price on POI","description":"Sets a pending price on a POI. The POI will wait for a customer scan until the TTL expires.","operationId":"setPOIPrice","parameters":[{"name":"poiId","in":"path","description":"The POI ID","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/POIPriceRequest"}}},"required":true},"responses":{"409":{"description":"POI is disabled or already has a pending price","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"POI not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Price set successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/POIPriceResponse"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["POI"],"summary":"Cancel pending price","description":"Cancels any pending price on a POI, resetting it to IDLE state","operationId":"cancelPOIPrice","parameters":[{"name":"poiId","in":"path","description":"The POI ID","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Price cancelled successfully"},"409":{"description":"No pending payment to cancel","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"POI not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval/{requestId}/cancel":{"put":{"tags":["Reports"],"summary":"Cancel running report or export","description":"Cancels a running report execution, given its request ID, or a running export, given its export ID","operationId":"cancelReport","parameters":[{"name":"requestId","in":"path","description":"Report request ID or export ID to cancel","required":true,"schema":{"type":"string"},"example":"1a81220c-2e38-4759-b067-c81abf176295"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Task cancelled successfully","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Request or export not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/schedules":{"get":{"tags":["Products / Schedules"],"summary":"Get all product schedules","description":"Retrieves all price schedules for a specific product","operationId":"getProductSchedules","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Schedules retrieved successfully","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleDTO"}}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["Products / Schedules"],"summary":"Create price schedule","description":"Creates a new price schedule for a product with time-constrained pricing (discounts or increments)","operationId":"createSchedule","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"requestBody":{"description":"Schedule details including price correction and date range","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleRequest"}}},"required":true},"responses":{"400":{"description":"Invalid schedule data","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"201":{"description":"Schedule created successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleDTO"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/placements":{"get":{"tags":["Products / Placements"],"summary":"List a product's placements","operationId":"listPlacements","parameters":[{"name":"productId","in":"path","description":"Product id","required":true,"schema":{"type":"string"},"example":"pr7e4rCToG"}],"responses":{"200":{"description":"Placements","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlacementDTO"}}}}},"404":{"description":"Product not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["Products / Placements"],"summary":"Create a placement","description":"Up to 1,000 per product. The response carries the new pl id","operationId":"createPlacement","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementDTO"}}}},"404":{"description":"ERR_MISSING_PRODUCT or ERR_MISSING_CAMPAIGN","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Invalid placement, medium, carriers or regions, or the limit is reached","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/audios/{id}/transfer":{"post":{"tags":["Products / Audios"],"summary":"Transfer audio to another product","description":"Reassigns an audio soundbite to a different product within the same shop. The fingerprint is preserved (no re-upload); only the product association changes. Cross-shop and cross-merchant transfers are rejected - move the product to the target shop instead.","operationId":"transferProductAudio","parameters":[{"name":"productId","in":"path","description":"Source product ID (current owner of the audio)","required":true,"schema":{"type":"string"},"example":"pr12345678"},{"name":"id","in":"path","description":"Audio ID to transfer","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"requestBody":{"description":"Target product for the transfer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioTransferRequest"}}},"required":true},"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Audio or target product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Invalid or missing target product","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Cross-shop or cross-merchant transfer is not allowed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Audio transferred successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AudioDTO"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/audios/upload":{"post":{"tags":["Products / Audios"],"summary":"Upload audio file","description":"Registers a new audio soundbite for a product by uploading an audio/video file of up to 100 MB holding 2 to 120 seconds of audio. Only the audio channel is extracted from video files.","operationId":"uploadProductAudio","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","description":"Audio file to upload (mp3, wav, etc.) - max 100 MB, 2 to 120 seconds","format":"binary"}}}}}},"responses":{"413":{"description":"File larger than 100 MB","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"This audio is already registered (deduplicated fingerprint)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"201":{"description":"Audio file uploaded and registered successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AudioDTO"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Invalid file, or audio shorter than 2 or longer than 120 seconds","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/campaigns":{"get":{"tags":["Campaigns"],"summary":"List campaigns","description":"The merchant's campaigns. An ISV acting for the merchant sees the ones it created and the ones holding placements in its shops","operationId":"listCampaigns","responses":{"200":{"description":"Campaigns","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CampaignDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["Campaigns"],"summary":"Create a campaign","operationId":"createCampaign","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRequest"}}},"required":true},"responses":{"400":{"description":"Invalid campaign","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CampaignDTO"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/oauth2/tokens":{"get":{"tags":["OAuth2"],"summary":"List all tokens","description":"Returns the OAuth2 authorization tokens of the authenticated ISV, one per merchant authorization in any status. A merchant that has been deleted is not listed: its authorization is revoked with it, and the ISV is told by the merchant.deleted callback.","operationId":"listOauth2Tokens","responses":{"404":{"description":"Caller is not an ISV","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Oauth2Token"}}}}},"200":{"description":"List of tokens","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Oauth2Token"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["OAuth2"],"summary":"Request authorization token","description":"Requests an OAuth2 authorization token for a merchant using client credentials. The token starts as PENDING until the merchant grants authorization. If an existing GRANTED authorization exists but the token credential has expired, a new credential is generated automatically without requiring merchant re-consent.","operationId":"requestOauth2Token","requestBody":{"description":"OAuth2 token request with client credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Oauth2RequestToken"}}},"required":true},"responses":{"404":{"description":"Caller is not an ISV","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Oauth2Token"}}}},"400":{"description":"Invalid request (unsupported grant type, missing fields, or client not found). Carries RFC 6749 section 5.2 `error` and `error_description` alongside payware's `errorCode`, and `WWW-Authenticate` on invalid_client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Oauth2Token"}}}},"200":{"description":"Token created or already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Oauth2Token"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/oauth2/tokens/{token}/rotate":{"post":{"tags":["OAuth2"],"summary":"Rotate token credential","description":"Generates a new token credential value and resets the expiration. The authorization grant (GRANTED status) is preserved. Only the ISV that owns the token can rotate it.","operationId":"rotateOauth2Token","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Token rotated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Oauth2Token"}}}},"404":{"description":"Token not found or caller is not an ISV","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Oauth2Token"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/transactions":{"post":{"tags":["Transactions"],"summary":"Generate new transaction","description":"Creates a new transaction with QR code or barcode for payment processing. The same path with a multipart/form-data body is soundbite recognition (an audio fingerprint), answered only at https://soundbite.payware.eu (sandbox: https://soundbite-sandbox.payware.eu); api.payware.eu and sandbox.payware.eu refuse it with 421 ERR_SOUNDBITE_HOST.","operationId":"generateTransaction","parameters":[{"name":"Soundbite-Session","in":"header","description":"Optional: one random UUID per tap, the same on every query of that tap, so its answers keep one id. Ignored when malformed","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. A key of your choosing, unique per request (a UUID is typical), 1-255 printable ASCII characters without spaces. A retry with the same key and the same body, within 24 hours, gets the first call's response back with the header Idempotent-Replayed: true instead of creating a second transaction. The same key with a different body answers 422 ERR_IDEMPOTENCY_KEY_REUSED; a retry while the first call is still running answers 409 ERR_IDEMPOTENCY_KEY_IN_PROGRESS. Only successful responses are kept, so a call that failed can be retried with the same key.","required":false,"schema":{"maxLength":255,"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","description":"Audio fingerprint file generated by the payware SDK for soundbite recognition","format":"binary"}}}},"application/json":{"schema":{"$ref":"#/components/schemas/TransactionRequest"}}},"required":true},"responses":{"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Transaction created successfully. A replay of an earlier call with the same Idempotency-Key carries the header Idempotent-Replayed: true.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/TransactionResponse"},{"$ref":"#/components/schemas/TransactionDTO"}]}}}},"400":{"description":"Invalid request parameters, or an invalid Idempotency-Key (ERR_INVALID_IDEMPOTENCY_KEY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"The referenced product does not exist or is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"ERR_RECOGNITION_BUSY - recognition is at capacity. Keep the recording and send it again after the Retry-After header's seconds; the window was not evaluated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized - Invalid or missing authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"ERR_IDEMPOTENCY_KEY_REUSED - the Idempotency-Key was used in the last 24 hours for a request with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"ERR_IDEMPOTENCY_KEY_IN_PROGRESS - a request with the same Idempotency-Key is still running. Retry shortly to get its response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/transactions/{transactionId}":{"get":{"tags":["Transactions"],"summary":"Get transaction data","description":"Retrieves transaction or product details by transaction ID. For shippable products (pr/ps prefix), returns product details.","operationId":"getTransaction","parameters":[{"name":"transactionId","in":"path","description":"Transaction ID or Product ID (for shippable products)","required":true,"schema":{"type":"string"},"example":"pw12345678"}],"responses":{"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Transaction or product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Transaction data retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionDTO"}}}},"400":{"description":"Invalid transaction ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["Transactions"],"summary":"Process transaction","description":"Processes an existing transaction by transaction ID with updated details","operationId":"processTransaction","parameters":[{"name":"transactionId","in":"path","description":"Transaction ID to process","required":true,"schema":{"type":"string"},"example":"pw12345678"},{"name":"Idempotency-Key","in":"header","description":"Optional. A key of your choosing, unique per request (a UUID is typical), 1-255 printable ASCII characters without spaces. A retry with the same key and the same body, within 24 hours, gets the first call's response back with the header Idempotent-Replayed: true instead of creating a second transaction. The same key with a different body answers 422 ERR_IDEMPOTENCY_KEY_REUSED; a retry while the first call is still running answers 409 ERR_IDEMPOTENCY_KEY_IN_PROGRESS. Only successful responses are kept, so a call that failed can be retried with the same key.","required":false,"schema":{"maxLength":255,"type":"string"}}],"requestBody":{"description":"Updated transaction details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionRequest"}}},"required":true},"responses":{"422":{"description":"ERR_IDEMPOTENCY_KEY_REUSED - the Idempotency-Key was used in the last 24 hours for a request with a different path or body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Transaction not found (ERR_MISSING_TRANSACTION), or it has expired (ERR_TRANSACTION_EXPIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"The transaction could not be priced: no fee configuration exists for its currency (ERR_FEE_CONFIGURATION_UNAVAILABLE), or no exchange rate was available to express the EUR fixed fee in the transaction's currency (ERR_MISSING_EXCHANGE_RATE). Both are payware-side configuration gaps - the caller did nothing wrong and the request was not applied, so retrying later is correct.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"ERR_ALREADY_PROCESSED - the transaction has already been processed by another partner or with a different body. The request was well formed; this is the answer to a conflicting submission, not to a bad one. Thrown by both the FI and merchant validators. Also ERR_IDEMPOTENCY_KEY_IN_PROGRESS - a request with the same Idempotency-Key is still running; retry shortly to get its response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Transaction processed successfully. A replay of an earlier call with the same Idempotency-Key carries the header Idempotent-Replayed: true. Processing the same transaction again, by the same partner with the same body, returns it as stored without changing it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionResponse"}}}},"400":{"description":"Invalid transaction ID or request parameters, or an invalid Idempotency-Key (ERR_INVALID_IDEMPOTENCY_KEY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["Transactions"],"summary":"Finalize transaction","description":"Updates transaction status to finalize or cancel the transaction","operationId":"finalizeTransaction","parameters":[{"name":"transactionId","in":"path","description":"Transaction ID to finalize","required":true,"schema":{"type":"string"},"example":"pw12345678"}],"requestBody":{"description":"Transaction status update request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionStatusUpdateRequest"}}},"required":true},"responses":{"409":{"description":"ERR_ALREADY_PROCESSED - the transaction has already been finalized. The request was well formed; this is the answer to a duplicate submission, not to a bad one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"The fee could not be recomputed for validation: no fee configuration exists for the transaction's currency (ERR_FEE_CONFIGURATION_UNAVAILABLE), or no exchange rate was available (ERR_MISSING_EXCHANGE_RATE). payware-side configuration gaps - the request was not applied, so retrying later is correct.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Transaction not found (ERR_MISSING_TRANSACTION), or it has expired (ERR_TRANSACTION_EXPIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Transaction finalized successfully. Repeating a finalize already applied, by the same bank with the same status, status message and amount, returns the stored result without applying it again or sending a second callback.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionDTO"}}}},"400":{"description":"Invalid transaction ID or status. Includes ERR_FEE_MISMATCH, which is what a caller gets for recomputing the fee instead of echoing back the `fee` from the process response - the comparison is for exact equality.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/transactions/recognitions/{recognitionId}":{"post":{"tags":["Transactions"],"summary":"Report the shopper's answer to a soundbite recognition","description":"After a soundbite answer with recognition.confidence PROBABLE, the wallet asks the shopper \"Is this the ad?\" and reports the answer here, with the recognition.id of that answer. Measurement only: nothing is stored and nothing about the transaction changes. Send it fire-and-forget; a failure must never reach the shopper. Restricted to active banks. Accepts the recognition-only token (\"scope\": \"soundbite\") described on POST /api/transactions, and like it is answered only at the soundbite hosts: api.payware.eu and sandbox.payware.eu refuse it with 421 ERR_SOUNDBITE_HOST.","operationId":"reportRecognitionAnswer","parameters":[{"name":"recognitionId","in":"path","description":"recognition.id from the soundbite answer","required":true,"schema":{"type":"string"},"example":"3f2b8c1e-6a4d-4e2f-9b1a-5c7d8e9f0a1b"}],"requestBody":{"description":"The shopper's answer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecognitionFeedbackRequest"}}},"required":true},"responses":{"403":{"description":"ERR_UNAUTHORIZED_OPERATION - the caller is not an active bank","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"204":{"description":"Answer recorded"},"400":{"description":"ERR_INVALID_UUID - recognitionId is not a UUID; ERR_INVALID_RECOGNITION_ANSWER - answer is neither CONFIRMED nor REJECTED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"servers":[{"url":"https://soundbite.payware.eu","description":"Production Server"},{"url":"https://soundbite-sandbox.payware.eu","description":"Sandbox Server"},{"url":"http://localhost:8080","description":"Local Development Server"}]}},"/api/products":{"get":{"tags":["Products"],"summary":"Get all products","description":"Retrieves a list of all products available to the authenticated merchant","operationId":"getAllProducts","responses":{"200":{"description":"Products retrieved successfully","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProductDTO"}}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized - Invalid or missing authentication","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - Requires PRM authority","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["Products"],"summary":"Create product","description":"Creates a new product with the specified details","operationId":"createProduct","requestBody":{"description":"Product details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductRequest"}}},"required":true},"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Product created successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProductDTO"}}}},"400":{"description":"Invalid product data","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/image":{"get":{"tags":["Products"],"summary":"Generate product image (GET)","description":"Generates a QR code or barcode image for the product with specified type and format","operationId":"getProductImage","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"},{"name":"type","in":"query","description":"Image type (QR or BARCODE)","required":true,"schema":{"type":"string","enum":["PLAIN","QR","BARCODE"]}},{"name":"format","in":"query","description":"Image format (PNG, SVG, etc.)","required":true,"schema":{"type":"string","enum":["PNG","JPG","SVG"]}}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Invalid parameters","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Image generated successfully","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["Products"],"summary":"Generate product image (POST)","description":"Generates a QR code or barcode image for the product with detailed options","operationId":"generateProductImage","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"requestBody":{"description":"Image generation options","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageRequest"}}},"required":true},"responses":{"200":{"description":"Image generated successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ImageResponse"}}}},"400":{"description":"Invalid image request","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/poi":{"get":{"tags":["POI"],"summary":"List all POIs","description":"Retrieves all POIs belonging to the authenticated merchant","operationId":"listPOIs","responses":{"200":{"description":"POIs retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/POIResponse"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["POI"],"summary":"Create a new POI","description":"Creates a new Point of Interaction for the authenticated merchant","operationId":"createPOI","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/POICreateRequest"}}},"required":true},"responses":{"404":{"description":"Shop not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"201":{"description":"POI created successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/POIResponse"}}}},"400":{"description":"Invalid request","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/poi/batch":{"post":{"tags":["POI"],"summary":"Create multiple POIs","description":"Creates multiple Points of Interaction in a single atomic call. Maximum 50 POIs per request.","operationId":"createPOIBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/POIBatchCreateRequest"}}},"required":true},"responses":{"400":{"description":"Invalid request (batch too large, empty, invalid TTL or callback URL)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Shop not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"201":{"description":"POIs created successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/POIBatchCreateResponse"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/isv/invitations":{"get":{"tags":["ISV Invitations"],"summary":"List invitations","description":"Lists all invitations created by this ISV with pagination and optional status filtering.","operationId":"listInvitations","parameters":[{"name":"status","in":"query","description":"Filter by status. Multiple values allowed: PENDING, COMPLETED, EXPIRED, CANCELLED","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"page","in":"query","description":"Page number (zero-based)","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","description":"Page size (max 100)","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"Paginated list of invitations","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageInvitationListItem"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["ISV Invitations"],"summary":"Create merchant invitation","description":"Creates a new invitation for a merchant to join payware via this ISV. Returns an invitation link that the ISV must deliver to the merchant. No email is sent - the ISV distributes the link through their own channels (email, SMS, in-app, etc.). The invitation type is auto-detected: REGISTRATION for new merchants, AUTHORIZATION_ONLY for existing ones.","operationId":"createInvitation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvitationRequest"}}},"required":true},"responses":{"400":{"description":"Invalid request data","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"201":{"description":"Invitation created successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateInvitationResponse"}}}},"409":{"description":"A pending invitation already exists for this email, or the merchant is already authorized by this ISV","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval":{"post":{"tags":["Reports"],"summary":"Run report asynchronously","description":"Executes a report generation request asynchronously and returns a request ID for tracking","operationId":"runReportAsync","requestBody":{"description":"Data retrieval request with report parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataRetrievalRequest"}}},"required":true},"responses":{"403":{"description":"ERR_REPORT_NOT_AVAILABLE - the report exists but is not available to this caller's plan or partner type. Distinct from 404, which means no such report is registered at all. Call GET /api/data-retrieval/reports to see what this caller may actually run; that endpoint and this check share one rule, so they cannot drift.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Report execution started successfully","content":{"*/*":{"schema":{"type":"string"}}}},"400":{"description":"ERR_INVALID_DATA_RETRIEVAL_REQUEST - the request could not be interpreted.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"ERR_REPORT_UNIT_ID_NOT_FOUND - no report is registered under that id.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval/request/{requestId}/export/{outputFormat}":{"post":{"tags":["Reports"],"summary":"Export report asynchronously","description":"Exports a completed report to the specified format (PDF, Excel, CSV, etc.)","operationId":"exportReportAsync","parameters":[{"name":"requestId","in":"path","description":"Report request ID","required":true,"schema":{"type":"string"},"example":"req123456"},{"name":"outputFormat","in":"path","description":"Output format (pdf, xlsx, csv, etc.)","required":true,"schema":{"type":"string"},"example":"pdf"}],"responses":{"200":{"description":"Export started successfully","content":{"*/*":{"schema":{"type":"string"}}}},"400":{"description":"Invalid export format or request","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Request not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/schedules/{id}":{"get":{"tags":["Products / Schedules"],"summary":"Get schedule by ID","description":"Retrieves a specific price schedule by its ID","operationId":"getScheduleById","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"},{"name":"id","in":"path","description":"Schedule ID","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Schedule not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Schedule retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleDTO"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Products / Schedules"],"summary":"Delete price schedule","description":"Deletes a specific price schedule by its ID","operationId":"deleteSchedule","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"},{"name":"id","in":"path","description":"Schedule ID to delete","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Schedule not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"204":{"description":"Schedule deleted successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleDTO"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["Products / Schedules"],"summary":"Update price schedule","description":"Updates an existing price schedule with new details","operationId":"updateSchedule","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"},{"name":"id","in":"path","description":"Schedule ID to update","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"requestBody":{"description":"Updated schedule details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleRequest"}}},"required":true},"responses":{"400":{"description":"Invalid schedule data","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Schedule updated successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleDTO"}}}},"404":{"description":"Schedule not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/audios/{id}":{"get":{"tags":["Products / Audios"],"summary":"Get audio by ID","description":"Retrieves a specific audio soundbite by its ID","operationId":"getAudioById","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"},{"name":"id","in":"path","description":"Audio ID","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"responses":{"200":{"description":"Audio retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AudioDTO"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Audio not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Products / Audios"],"summary":"Delete audio","description":"Deletes a specific audio soundbite by its ID","operationId":"deleteProductAudio","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"},{"name":"id","in":"path","description":"Audio ID to delete","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"204":{"description":"Audio deleted successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AudioDTO"}}}},"404":{"description":"Audio not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["Products / Audios"],"summary":"Update audio metadata","description":"Updates the metadata (title, product assignment) of an existing audio soundbite","operationId":"updateProductAudio","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"},{"name":"id","in":"path","description":"Audio ID to update","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"requestBody":{"description":"Updated audio metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioRequest"}}},"required":true},"responses":{"400":{"description":"Invalid audio data","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Audio not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Audio updated successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AudioDTO"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}":{"get":{"tags":["Products"],"summary":"Get product by ID","description":"Retrieves a specific product by its unique product ID","operationId":"getProductById","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"responses":{"200":{"description":"Product retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProductDTO"}}}},"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Products"],"summary":"Delete product","description":"Deletes a product by its ID","operationId":"deleteProduct","parameters":[{"name":"productId","in":"path","description":"Product ID to delete","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Product deleted successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProductDTO"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["Products"],"summary":"Update product","description":"Updates an existing product with new details","operationId":"updateProduct","parameters":[{"name":"productId","in":"path","description":"Product ID to update","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"requestBody":{"description":"Updated product details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductRequest"}}},"required":true},"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Product updated successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProductDTO"}}}},"400":{"description":"Invalid product data","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/placements/{placementId}/stats":{"get":{"tags":["Products / Placements"],"summary":"Placement results","description":"Offers shown and payments started and confirmed, over [from, to). Defaults to the last 30 days; at most 400 days","operationId":"getPlacementStats","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","description":"Start, a date (UTC midnight) or an ISO-8601 instant","required":false,"schema":{"type":"string"},"example":"2026-10-01"},{"name":"to","in":"query","description":"End, exclusive, a date or an ISO-8601 instant","required":false,"schema":{"type":"string"},"example":"2026-11-01"}],"responses":{"200":{"description":"Results","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementStatsDTO"}}}},"400":{"description":"Invalid date range","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/placements/{placementId}/link":{"get":{"tags":["Products / Placements"],"summary":"Placement short link","description":"https://go.payware.eu/{placementId}, made on first request. On a phone it opens payware:/{placementId} in the payment app","operationId":"getPlacementLink","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The link","content":{"*/*":{"schema":{"type":"string"}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"The shareable link could not be generated. Please try again.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/placements/{placementId}/image":{"get":{"tags":["Products / Placements"],"summary":"Placement QR code or barcode","description":"The QR code carries payware://{placementId}; the barcode (Code 128) carries the plain id","operationId":"getPlacementImage","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}},{"name":"type","in":"query","description":"QR or BARCODE","required":true,"schema":{"type":"string","enum":["PLAIN","QR","BARCODE"]},"example":"QR"},{"name":"format","in":"query","description":"PNG, JPG or SVG","required":true,"schema":{"type":"string","enum":["PNG","JPG","SVG"]},"example":"SVG"}],"responses":{"200":{"description":"The image","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/placements/{placementId}/airings/next":{"get":{"tags":["Products / Placements / Airings"],"summary":"The placement's next airings","description":"In each rule's time zone, so daylight-saving shifts are visible","operationId":"nextAirings","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"placementId","in":"path","required":true,"schema":{"type":"string"}},{"name":"count","in":"query","description":"How many, 1-100; default 10","required":false,"schema":{"type":"integer","format":"int32"},"example":10}],"responses":{"200":{"description":"Occurrences","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiringOccurrenceDTO"}}}}},"404":{"description":"Placement not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/audios":{"get":{"tags":["Products / Audios"],"summary":"Get all product audios","description":"Retrieves all audio soundbites registered for a specific product","operationId":"getProductAudios","parameters":[{"name":"productId","in":"path","description":"Product ID","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Audios retrieved successfully","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AudioDTO"}}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/placements/calendar":{"get":{"tags":["Products / Placements / Airings"],"summary":"Every airing in a time range","description":"All occurrences of the merchant's placements between from and to, ordered by start time, each in its rule's time zone. The range may span at most 400 days.","operationId":"airingCalendar","parameters":[{"name":"from","in":"query","description":"Start of the range: a date (the start of that day in UTC) or an ISO-8601 instant with an offset","required":true,"schema":{"type":"string"},"example":"2026-10-19"},{"name":"to","in":"query","description":"End of the range, after from, in the same forms","required":true,"schema":{"type":"string"},"example":"2026-10-26"}],"responses":{"400":{"description":"ERR_INVALID_DATE_FORMAT, ERR_INVALID_DATE_RANGE","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Occurrences","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiringOccurrenceDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/campaigns/{campaignId}/stats":{"get":{"tags":["Campaigns"],"summary":"Campaign results","description":"Offers shown and payments started and confirmed, over [from, to). Defaults to the last 30 days; at most 400 days","operationId":"getCampaignStats","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","description":"Start, a date (UTC midnight) or an ISO-8601 instant","required":false,"schema":{"type":"string"},"example":"2026-10-01"},{"name":"to","in":"query","description":"End, exclusive, a date or an ISO-8601 instant","required":false,"schema":{"type":"string"},"example":"2026-11-01"}],"responses":{"200":{"description":"Results","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementStatsDTO"}}}},"404":{"description":"Campaign not found.","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Invalid date range","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/oauth2/tokens/{token}":{"get":{"tags":["OAuth2"],"summary":"Get token status","description":"Retrieves the status of a specific OAuth2 authorization token.","operationId":"getOauth2Token","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Token found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Oauth2Token"}}}},"404":{"description":"Token not found or caller is not an ISV","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Oauth2Token"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/transactions/{transactionId}/link":{"get":{"tags":["Transactions"],"summary":"Get shareable link","description":"Generates a shareable link for the transaction that can be shared with customers","operationId":"getTransactionLink","parameters":[{"name":"transactionId","in":"path","description":"Transaction ID for which to generate shareable link","required":true,"schema":{"type":"string"},"example":"pw12345678"}],"responses":{"500":{"description":"Error generating shareable link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Shareable link generated successfully","content":{"application/json":{"schema":{"type":"string"}}}},"404":{"description":"Transaction not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Invalid transaction ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Transactions"],"summary":"Delete shareable link","description":"Deletes the shareable link associated with the transaction","operationId":"deleteTransactionLink","parameters":[{"name":"transactionId","in":"path","description":"Transaction ID for which to delete shareable link","required":true,"schema":{"type":"string"},"example":"pw12345678"}],"responses":{"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Invalid transaction ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Shareable link deleted successfully","content":{"application/json":{"schema":{"type":"string"}}}},"404":{"description":"Transaction or link not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/transactions-history/{transactionId}":{"get":{"tags":["Transactions"],"summary":"Get processed transaction information","description":"Fetches information of an expired or completed transaction. Requires the Standard or Premium plan; for an ISV acting on behalf of a merchant it is the merchant's plan that applies.","operationId":"getTransactionHistory","parameters":[{"name":"transactionId","in":"path","description":"Transaction ID of completed or expired transaction","required":true,"schema":{"type":"string"},"example":"pw7e4rCToG"}],"responses":{"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Transaction data retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionDTO"}}}},"400":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Transaction is missing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/shops":{"get":{"tags":["Shops"],"summary":"List all shops","description":"Retrieves all shops belonging to the authenticated merchant","operationId":"listShops","responses":{"200":{"description":"Shops retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ShopDTO"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/products/{productId}/link":{"get":{"tags":["Products"],"summary":"Generate product link","description":"Generates a shareable payment link for the product","operationId":"generateProductLink","parameters":[{"name":"productId","in":"path","description":"Product ID for link generation","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Link generated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Products"],"summary":"Delete product link","description":"Deletes the shareable payment link for the product","operationId":"deleteProductLink","parameters":[{"name":"productId","in":"path","description":"Product ID for link deletion","required":true,"schema":{"type":"string"},"example":"pr12345678"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Link deleted successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProductDTO"}}}},"401":{"description":"Unauthorized","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Product or link not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/poi/{poiId}":{"get":{"tags":["POI"],"summary":"Get POI details","description":"Retrieves details of a specific POI by its ID","operationId":"getPOI","parameters":[{"name":"poiId","in":"path","description":"The POI ID","required":true,"schema":{"type":"string"}}],"responses":{"404":{"description":"POI not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"POI retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/POIResponse"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/poi/{poiId}/status":{"get":{"tags":["POI"],"summary":"Get POI status","description":"Retrieves the current status of a POI including any pending payment. A POI returns to IDLE as soon as it is scanned, so pass the sessionToken returned by the price push to also get the transaction created for that session and its current status (transactionId, transactionStatus). Keep the session token until the status is final: CONFIRMED, DECLINED, FAILED, CANCELLED or EXPIRED. The fields are empty until the POI is scanned, and for a token that does not belong to this POI.","operationId":"getPOIStatus","parameters":[{"name":"poiId","in":"path","description":"The POI ID","required":true,"schema":{"type":"string"}},{"name":"sessionToken","in":"query","description":"Session token from the price push; returns that session's transaction and its status","required":false,"schema":{"type":"string"}}],"responses":{"404":{"description":"POI not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"POI status retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/POIStatusResponse"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/poi/{poiId}/image":{"get":{"tags":["POI"],"summary":"Get POI QR code","description":"Generates a QR code image for a POI that customers can scan","operationId":"getPOIQRCode","parameters":[{"name":"poiId","in":"path","description":"The POI ID","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","description":"Image format (PNG, SVG, JPG)","required":false,"schema":{"type":"string","default":"PNG","enum":["PNG","JPG","SVG"]}}],"responses":{"200":{"description":"QR code generated successfully","content":{"image/png":{}}},"404":{"description":"POI not found","content":{"image/png":{"schema":{"$ref":"#/components/schemas/ApiError"}},"image/svg+xml":{"schema":{"$ref":"#/components/schemas/ApiError"}},"image/jpeg":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/logs":{"get":{"tags":["Logs"],"summary":"Query logs","description":"Query logs for the authenticated tenant. Returns paginated JSON results.","operationId":"queryLogs","parameters":[{"name":"from","in":"query","description":"Start timestamp (ISO 8601)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"End timestamp (ISO 8601)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"level","in":"query","description":"Filter by log level: DEBUG, INFO, WARN, ERROR","required":false,"schema":{"type":"string"}},{"name":"logger","in":"query","description":"Filter by logger name (partial match)","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","description":"Search in message content","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum records to return (default 1000, max 10000)","required":false,"schema":{"type":"integer","format":"int32","default":1000}},{"name":"cursor","in":"query","description":"Pagination cursor from previous response","required":false,"schema":{"type":"string"}}],"responses":{"401":{"description":"Unauthorized - invalid or missing JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LogQueryResponse"}}}},"200":{"description":"Logs retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LogQueryResponse"}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LogQueryResponse"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/logs/stream":{"get":{"tags":["Logs"],"summary":"Stream logs as NDJSON","description":"Stream logs as newline-delimited JSON for real-time processing.","operationId":"streamLogs","parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"application/x-ndjson":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/logs/status":{"get":{"tags":["Logs"],"summary":"Get log status","description":"Get information about available logs for the authenticated tenant.","operationId":"getLogStatus","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LogStatusResponse"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/logs/download":{"get":{"tags":["Logs"],"summary":"Download logs as compressed archive","description":"Download logs for a date range as a gzipped file.","operationId":"downloadLogs","parameters":[{"name":"from","in":"query","description":"Start timestamp (ISO 8601)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"End timestamp (ISO 8601)","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/isv/reference/legal-forms":{"get":{"tags":["ISV Reference Data"],"summary":"Get legal forms for a jurisdiction","description":"Returns legal forms available in the specified jurisdiction.","operationId":"getLegalForms","parameters":[{"name":"jurisdictionCode","in":"query","description":"ISO 3166-1 alpha-2 country code (e.g. BG, DE, ES)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LegalFormDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/isv/reference/languages":{"get":{"tags":["ISV Reference Data"],"summary":"Get supported languages","description":"Returns languages supported by payware.","operationId":"getLanguages","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LanguageDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/isv/reference/jurisdictions":{"get":{"tags":["ISV Reference Data"],"summary":"Get jurisdictions","description":"Returns countries/jurisdictions where payware operates.","operationId":"getJurisdictions","parameters":[{"name":"languageCode","in":"query","description":"ISO 639-1 language code (e.g. en, bg, es). Defaults to English.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JurisdictionDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/isv/reference/currencies":{"get":{"tags":["ISV Reference Data"],"summary":"Get available currencies","description":"Returns all supported currencies.","operationId":"getCurrencies","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CurrencyDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/isv/reference/business-activities":{"get":{"tags":["ISV Reference Data"],"summary":"Get business activities list","description":"Returns business activity categories.","operationId":"getBusinessActivities","parameters":[{"name":"languageCode","in":"query","description":"ISO 639-1 language code (e.g. en, bg, es). Defaults to English.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BusinessActivityDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/isv/invitations/{invitationId}":{"get":{"tags":["ISV Invitations"],"summary":"Get invitation details","description":"Retrieves full details of a specific invitation including status, pre-filled merchant data, and invitation link.","operationId":"getInvitation","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"404":{"description":"Invitation not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Invitation details","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InvitationDetailResponse"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["ISV Invitations"],"summary":"Cancel invitation","description":"Cancels a pending invitation. Only invitations with status PENDING can be cancelled. The invitation link becomes invalid immediately.","operationId":"cancelInvitation","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"404":{"description":"Invitation not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"204":{"description":"Invitation cancelled successfully"},"409":{"description":"Invitation is not in PENDING status and cannot be cancelled","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/isv/consent-config":{"get":{"tags":["ISV"],"summary":"Get consent configuration","description":"Returns the consent checkboxes, plan options, and T&C effective date required for merchant registration. Content is localized based on the Accept-Language header. Checkbox labels contain {isvName} and {companyName} placeholder tokens that must be replaced by the ISV before display.","operationId":"getConsentConfig","parameters":[{"name":"Accept-Language","in":"header","description":"Language for localized content (e.g. en, bg, es)","required":false,"schema":{"type":"string","default":"en"}}],"responses":{"200":{"description":"Consent configuration","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentConfigResponse"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval/{reportId}":{"get":{"tags":["Reports"],"summary":"Get report requests","description":"Retrieves all report execution requests for a specific report ID","operationId":"getReportRequests","parameters":[{"name":"reportId","in":"path","description":"Report ID","required":true,"schema":{"type":"string"},"example":"transaction_summary"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Report not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Report requests retrieved successfully","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReportRequestDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval/request/{requestId}/status":{"get":{"tags":["Reports"],"summary":"Get report execution status","description":"Retrieves the current status of a report execution request","operationId":"getReportStatus","parameters":[{"name":"requestId","in":"path","description":"Report request ID","required":true,"schema":{"type":"string"},"example":"req123456"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Status retrieved successfully","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Request not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval/reports":{"get":{"tags":["Reports"],"summary":"Get all available reports","description":"Retrieves a list of all available reports for the authenticated user","operationId":"getAllReports","responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Reports retrieved successfully","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReportDTO"}}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval/exports/{requestId}":{"get":{"tags":["Reports"],"summary":"Get exports for request","description":"Retrieves all export attempts for a specific report request","operationId":"getReportExports","parameters":[{"name":"requestId","in":"path","description":"Report request ID","required":true,"schema":{"type":"string"},"example":"req123456"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Exports retrieved successfully","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReportRequestDTO"}}}}},"404":{"description":"Request not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval/export/{exportId}/status":{"get":{"tags":["Reports"],"summary":"Get export execution status","description":"Retrieves the current status of a report export operation","operationId":"getExportStatus","parameters":[{"name":"exportId","in":"path","description":"Export ID","required":true,"schema":{"type":"string"},"example":"exp123456"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Export not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Status retrieved successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/data-retrieval/export/{exportId}/download":{"get":{"tags":["Reports"],"summary":"Download report","description":"Downloads the exported report file","operationId":"downloadReport","parameters":[{"name":"exportId","in":"path","description":"Export ID","required":true,"schema":{"type":"string"},"example":"exp123456"}],"responses":{"500":{"description":"Internal server error","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"200":{"description":"Report downloaded successfully","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Export not found or not ready","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Unauthenticated - missing, malformed or expired credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Forbidden - the caller is authenticated but not permitted (plan or capability gate, KYC state, or tenant scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many requests - the caller exceeded its per-partner rate limit. Carries errorCode ERR_RATE_LIMIT_EXCEEDED and a Retry-After header, in seconds. The request was not processed, so the identical request is safe to retry once the window has passed.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","format":"int32","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"AiringRuleRequest":{"required":["frequency","startDate","windows"],"type":"object","properties":{"frequency":{"type":"string","description":"ONCE, DAILY, WEEKLY or MONTHLY","example":"DAILY"},"repeatEvery":{"maximum":366,"minimum":1,"type":"integer","description":"Every N days, weeks or months; default 1","format":"int32","example":1},"startDate":{"type":"string","description":"First day, YYYY-MM-DD, local to timeZone","example":"2026-10-15"},"endDate":{"type":"string","description":"Last day, YYYY-MM-DD; at most 366 days after the start. Empty means open-ended","example":"2026-12-31"},"timeZone":{"type":"string","description":"IANA time zone; default the product's","example":"Europe/Sofia"},"daysOfWeek":{"type":"array","description":"WEEKLY: the days it airs on","example":["MONDAY","THURSDAY"],"items":{"type":"string","description":"WEEKLY: the days it airs on","example":"[\"MONDAY\",\"THURSDAY\"]"}},"monthDays":{"type":"array","description":"MONTHLY by date: days of the month (a day the month lacks is skipped)","example":[1,15],"items":{"type":"integer","description":"MONTHLY by date: days of the month (a day the month lacks is skipped)","format":"int32"}},"monthWeek":{"type":"integer","description":"MONTHLY by weekday: 1-5, or -1 for the last; with monthWeekday","format":"int32","example":1},"monthWeekday":{"type":"string","description":"MONTHLY by weekday: the weekday","example":"MONDAY"},"windows":{"maxItems":24,"minItems":0,"type":"array","description":"Time windows on each day it airs, 1 to 24","items":{"$ref":"#/components/schemas/AiringWindowDTO"}},"excludedDates":{"maxItems":366,"minItems":0,"type":"array","description":"Days it does not air, YYYY-MM-DD","example":["2026-12-25"],"items":{"type":"string","description":"Days it does not air, YYYY-MM-DD","example":"[\"2026-12-25\"]"}},"expectedAudience":{"type":"integer","description":"Expected audience per airing, for the merchant's own planning","format":"int32","example":250000}}},"AiringWindowDTO":{"required":["end","start"],"type":"object","properties":{"start":{"pattern":"^\\d{2}:\\d{2}$","type":"string","description":"HH:mm","example":"08:00"},"end":{"pattern":"^\\d{2}:\\d{2}$","type":"string","description":"HH:mm; at most 6 hours after the start","example":"08:30"}}},"AiringRuleDTO":{"type":"object","properties":{"ruleId":{"type":"integer","format":"int32","example":17},"frequency":{"type":"string"},"repeatEvery":{"type":"integer","format":"int32"},"startDate":{"type":"string"},"endDate":{"type":"string"},"timeZone":{"type":"string"},"daysOfWeek":{"type":"array","items":{"type":"string"}},"monthDays":{"type":"array","items":{"type":"integer","format":"int32"}},"monthWeek":{"type":"integer","format":"int32"},"monthWeekday":{"type":"string"},"windows":{"type":"array","items":{"$ref":"#/components/schemas/AiringWindowDTO"}},"excludedDates":{"type":"array","items":{"type":"string"}},"expectedAudience":{"type":"integer","format":"int32"},"source":{"type":"string","description":"Who entered it","example":"MERCHANT"},"warnings":{"type":"array","description":"Returned on create and update only","items":{"$ref":"#/components/schemas/AiringWarningDTO"}}}},"AiringWarningDTO":{"type":"object","properties":{"code":{"type":"string","example":"AIRING_OVERLAP"},"placementId":{"type":"string","description":"The other placement","example":"pl3x9KmQ2a"},"at":{"type":"string","description":"First overlap, UTC, ISO-8601","example":"2026-10-15T05:00:00Z"}},"description":"Returned on create and update only"},"ApiError":{"type":"object","properties":{"error_description":{"type":"string"},"errorCode":{"type":"string"},"message":{"type":"string"},"correlationId":{"type":"string"},"error":{"type":"string"}}},"AiringBatchErrorDTO":{"type":"object","properties":{"errorCode":{"type":"string","example":"ERR_INVALID_AIRING_RULE"},"message":{"type":"string"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/AiringRowErrorDTO"}}}},"AiringRowErrorDTO":{"type":"object","properties":{"index":{"type":"integer","description":"Zero-based position in the request","format":"int32","example":2},"errorCode":{"type":"string","example":"ERR_INVALID_AIRING_WINDOW"},"message":{"type":"string"}}},"PlacementRequest":{"required":["carriers","medium","name"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","description":"Placement name, up to 100 characters","example":"Sofia metro posters, October"},"campaignId":{"type":"string","description":"The campaign it belongs to, if any","example":"cp7e4rCToG"},"medium":{"type":"string","description":"What the placement is: PRINT, PACKAGING, OUTDOOR, IN_STORE, EVENT, TV, RADIO, STREAMING, ONLINE, SOCIAL, EMAIL, SMS or OTHER","example":"OUTDOOR"},"carriers":{"maxItems":7,"minItems":0,"type":"array","description":"The methods that carry it: QR, BARCODE, NFC, BLE, LINK, SMS, SOUNDBITE (airs the product's audio)","example":["QR","NFC"],"items":{"type":"string","description":"The methods that carry it: QR, BARCODE, NFC, BLE, LINK, SMS, SOUNDBITE (airs the product's audio)","example":"[\"QR\",\"NFC\"]"}},"channel":{"maxLength":100,"minLength":0,"type":"string","description":"Descriptive, e.g. the TV channel or the website, up to 100 characters","example":"bTV"},"location":{"maxLength":255,"minLength":0,"type":"string","description":"Descriptive, e.g. the venue or the address, up to 255 characters","example":"Serdika metro station"},"externalRef":{"maxLength":100,"minLength":0,"type":"string","description":"An agency's own code, up to 100 characters"},"regions":{"maxItems":250,"minItems":0,"type":"array","description":"ISO 3166-1 alpha-2 codes of the countries it airs in; empty means anywhere. Matched against the paying bank's country","example":["BG"],"items":{"type":"string","description":"ISO 3166-1 alpha-2 codes of the countries it airs in; empty means anywhere. Matched against the paying bank's country","example":"[\"BG\"]"}},"active":{"type":"boolean","description":"Whether it is in use. Governs airing and the soundbite attribution; a printed code keeps resolving until the placement is deleted","example":true},"activeFrom":{"type":"string","description":"Start of its active window, ISO-8601 with offset; empty means the product's","example":"2026-10-15T00:00:00+03:00"},"activeTo":{"type":"string","description":"End of its active window, ISO-8601 with offset; empty means the product's","example":"2026-12-31T23:59:59+02:00"}}},"PlacementDTO":{"type":"object","properties":{"placementId":{"type":"string","description":"Placement id, pl + 8 characters. It travels on QR, NFC, BLE, links and barcodes like a product id","example":"pl7e4rCToG"},"productId":{"type":"string","example":"pr7e4rCToG"},"campaignId":{"type":"string","example":"cp7e4rCToG"},"name":{"type":"string"},"medium":{"type":"string","example":"OUTDOOR"},"carriers":{"type":"array","items":{"type":"string"}},"channel":{"type":"string"},"location":{"type":"string"},"externalRef":{"type":"string"},"regions":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"activeFrom":{"type":"string","description":"UTC, ISO-8601","example":"2026-10-14T21:00:00Z"},"activeTo":{"type":"string","description":"UTC, ISO-8601","example":"2026-12-31T21:59:59Z"},"link":{"type":"string","description":"Its short link on go.payware.eu, once made","example":"https://go.payware.eu/pl7e4rCToG"},"createdByIsv":{"type":"string","description":"Partner id of the ISV that created it for the merchant, if any"},"createdAt":{"type":"string","description":"UTC, ISO-8601"},"updatedAt":{"type":"string","description":"UTC, ISO-8601"}}},"CampaignRequest":{"required":["name"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","description":"Campaign name, up to 100 characters","example":"Autumn TV 2026"},"startsOn":{"type":"string","description":"First day, YYYY-MM-DD","example":"2026-10-15"},"endsOn":{"type":"string","description":"Last day, YYYY-MM-DD","example":"2026-12-31"},"status":{"type":"string","description":"DRAFT, ACTIVE or ENDED. Descriptive: it does not switch placements on or off","example":"ACTIVE"},"externalRef":{"maxLength":100,"minLength":0,"type":"string","description":"An agency's own campaign code, up to 100 characters","example":"AGY-2026-117"}}},"CampaignDTO":{"type":"object","properties":{"campaignId":{"type":"string","description":"Campaign id, cp + 8 characters","example":"cp7e4rCToG"},"name":{"type":"string"},"startsOn":{"type":"string","example":"2026-10-15"},"endsOn":{"type":"string","example":"2026-12-31"},"status":{"type":"string","example":"ACTIVE"},"externalRef":{"type":"string"},"createdByIsv":{"type":"string","description":"Partner id of the ISV that created the campaign for the merchant, if any"},"placementIds":{"type":"array","description":"The campaign's placements the caller can see","items":{"type":"string","description":"The campaign's placements the caller can see"}},"createdAt":{"type":"string","description":"UTC, ISO-8601","example":"2026-10-07T12:00:00Z"},"updatedAt":{"type":"string","description":"UTC, ISO-8601","example":"2026-10-07T12:00:00Z"}}},"POIPriceRequest":{"required":["amount","currency"],"type":"object","properties":{"amount":{"type":"number"},"currency":{"pattern":"^[A-Za-z]{3}$","type":"string"},"ttlSeconds":{"maximum":600,"minimum":60,"type":"integer","format":"int32"}}},"POIPriceResponse":{"type":"object","properties":{"poiId":{"type":"string"},"status":{"type":"string"},"sessionToken":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}},"ScheduleRequest":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"productId":{"type":"string"},"description":{"type":"string"},"priceCorrection":{"type":"string"},"correctionType":{"type":"string"},"correctionValue":{"type":"string"},"dateFrom":{"type":"string"},"dateTo":{"type":"string"}}},"ScheduleDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"productId":{"type":"string"},"description":{"type":"string"},"regularPrice":{"type":"string"},"salePrice":{"type":"string"},"priceCorrection":{"type":"string"},"correctionValue":{"type":"number"},"correctionType":{"type":"string"},"dateFrom":{"type":"string","format":"date-time"},"dateTo":{"type":"string","format":"date-time"}}},"AudioTransferRequest":{"type":"object","properties":{"targetProductId":{"type":"string"}}},"AudioDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"productId":{"type":"string"},"title":{"type":"string"},"folderId":{"type":"string"},"audioId":{"type":"string"},"status":{"type":"string"},"duration":{"type":"number","format":"double"},"uploadedAt":{"type":"string","format":"date-time"}}},"Oauth2RequestToken":{"type":"object","properties":{"grantType":{"type":"string","description":"Grant type. Only \"client_credentials\" is supported.","example":"client_credentials"},"clientId":{"type":"string","description":"The merchant's partnerId","example":"PZAYNMVE"},"clientSecret":{"type":"string","description":"Base64-encoded merchant pairing key. The field is named client_secret because RFC 6749 names it that; it is the value the merchant gave you so you can REQUEST authorization. The request is created PENDING and confers no access until the merchant grants it.","example":"YVlQMkxOdXQ0Y2RDQUdaYk5GQVA3VkpqMmxlQ0x1Z20="}},"description":"OAuth2 token request"},"Oauth2Token":{"type":"object","properties":{"clientId":{"type":"string","description":"The merchant's partnerId","example":"PZAYNMVE"},"accessToken":{"type":"string","description":"The access token","example":"aYP2LNut4cdCAGZbNFAP7VJj2leCLugm"},"tokenType":{"type":"string","description":"Token type. Only \"bearer\" is supported.","example":"bearer"},"expiresIn":{"type":"integer","description":"Seconds until this token credential stops being accepted, per the OAuth2 meaning of expires_in. A credential requested with POST /oauth2/tokens expires 180 days (by default) after the merchant grants authorization, and a rotated one 180 days after the rotation. NULL means the credential has no expiration date: credentials created by the invitation flow, the pre-provisioned sandbox test-merchant credentials, and legacy credentials issued before expiry was introduced, until they are rotated. 0 means already expired. Expiry ends the CREDENTIAL, not the merchant's authorization: rotate it (rotation works on an expired credential), or request a token again with the same client credentials, and if the authorization is still GRANTED a fresh credential is issued with no new merchant consent. Do not cache a credential indefinitely.","format":"int64","nullable":true,"example":15552000},"scope":{"type":"string","description":"Granted scopes","example":"resource-server-read resource-server-write"},"status":{"type":"string","description":"Token status. Only GRANTED tokens are valid for API requests.","enum":["PENDING","GRANTED","REVOKED"]}},"description":"OAuth2 token response"},"DeliveryAddressDTO":{"type":"object","properties":{"country":{"type":"string"},"fullName":{"type":"string"},"streetAddressLine1":{"type":"string"},"streetAddressLine2":{"type":"string"},"city":{"type":"string"},"region":{"type":"string"},"zipCode":{"type":"string"},"phoneNumber":{"type":"string"},"email":{"type":"string"}}},"ProductPresentationDTO":{"type":"object","properties":{"productId":{"type":"string","description":"Product reference identifier."},"type":{"type":"string","description":"Product type: ITEM or SERVICE."},"name":{"type":"string","description":"Structured product name."},"shortDescription":{"type":"string","description":"Short product description."},"longDescription":{"type":"string","description":"Long product description."},"imageUrl":{"type":"string","description":"Product image URL to display to the payer. Availability depends on merchant plan. Permitted image types: PNG, JPEG, WebP, GIF."},"imageDigest":{"type":"string","description":"SHA-256 hex digest of the image at imageUrl, pinned by payware. The institution must verify the fetched bytes against this digest before rendering and fall back to a neutral placeholder on mismatch."},"imageContentType":{"type":"string","description":"Content type of the image as observed by payware on fetch (e.g. image/png)."},"imageBytes":{"type":"integer","description":"Byte length of the image as observed by payware on fetch.","format":"int32"},"termsUrl":{"type":"string","description":"URL of the terms and conditions applying to the purchase. Availability depends on merchant plan."},"termsText":{"type":"string","description":"Inline terms and conditions text applying to the purchase."},"regularPrice":{"type":"string","description":"Product regular (pre-discount) list price, in the Transaction currency. Present only when it is higher than the Transaction amount, i.e. when there is a genuine saving to display; omitted when the amount equals or exceeds the regular price (a price schedule may set the sale price at or above the regular price). The Transaction amount and currency are authoritative and are not repeated here. For display only."},"shippable":{"type":"boolean","description":"Whether the product requires a delivery address."},"shopName":{"type":"string","description":"Merchant outlet (shop) name."},"quickPay":{"type":"boolean","description":"When true, the client application may skip the product detail screen and proceed directly to payment confirmation, provided the minimum transaction information and access to the terms in full remain available to the payer. Intended for high-speed, fixed-price scenarios such as transit gates, event entry, or toll booths. Product preview responses only."}},"description":"Product presentation block, present only for product-originated transactions."},"RecognitionDTO":{"type":"object","properties":{"confidence":{"type":"string","description":"CERTAIN: the ad was recognised. PROBABLE: the ad was probably recognised; ask the shopper to confirm it (\"Is this the ad?\") before continuing, and report the answer to POST /api/transactions/recognitions/{id}.","enum":["CERTAIN","PROBABLE"]},"id":{"type":"string","description":"Identifier of this recognition answer (UUID), used to report the shopper's confirmation.","example":"3f2b8c1e-6a4d-4e2f-9b1a-5c7d8e9f0a1b"}},"description":"Confidence of a soundbite recognition. Present on answers to soundbite fingerprints; a transaction preview without it is a certain answer."},"TransactionDTO":{"type":"object","properties":{"transactionId":{"type":"string"},"initiatingId":{"type":"string"},"transactionType":{"type":"string"},"initiatedBy":{"type":"string"},"payerBIC":{"type":"string"},"payerFriendlyName":{"type":"string"},"payerAccount":{"type":"string"},"payeeBIC":{"type":"string"},"payeeFriendlyName":{"type":"string"},"payeeAccount":{"type":"string"},"currency":{"type":"string"},"amount":{"type":"string","description":"Transaction amount, as a decimal string at the smallest unit `currency` can be paid in. That is not always two decimal places - it follows the currency. Parse it as a decimal, never as a fixed-width string, and do not compare amounts as strings."},"fee":{"type":"string","description":"The fee payware calculated and will enforce at finalize, as a decimal string at the smallest unit `currency` can be paid in - the amount the institution can actually withhold. Echo it back UNCHANGED at finalize: do not recompute it from feeFixed/feeRate and do not re-round it, or the call is rejected with ERR_FEE_MISMATCH. Omitted (not zero) when the transaction carries no recorded fee; absence means unknown, not free."},"reasonL1":{"type":"string"},"reasonL2":{"type":"string"},"created":{"type":"integer","format":"int64"},"finalized":{"type":"integer","description":"Finalization moment, UNIX epoch milliseconds. Omitted for EXPIRED transactions, which are closed by the platform's expiry sweep and carry no finalization moment.","format":"int64"},"timeToLive":{"type":"integer","format":"int32"},"status":{"type":"string","description":"Transaction status. ACTIVE = awaiting payment (initial state, only status returned by GET). CONFIRMED = payment completed successfully. CANCELLED = cancelled before completion (requires statusMessage). DECLINED = payment declined by financial institution (requires statusMessage). FAILED = processing failed (requires statusMessage). EXPIRED = TTL exceeded before payment.","enum":["ACTIVE","CONFIRMED","CANCELLED","DECLINED","FAILED","EXPIRED"]},"statusMessage":{"type":"string"},"paymentMethod":{"type":"string","description":"Payment method chosen by customer. Used by banks when processing transactions. A2A = direct transfer (lower fee, no rewards). CARD_FUNDED = card-linked account (higher fee, rewards eligible). BNPL = buy now pay later (installments). INSTANT_CREDIT = credit line approved at purchase.","enum":["A2A","CARD_FUNDED","BNPL","INSTANT_CREDIT"]},"passbackParams":{"type":"string","description":"Opaque string supplied by the initiating partner at creation and passed back unmodified on every response and callback for this transaction. payware never interprets it."},"payeeAmount":{"type":"string"},"payeeCurrencyCode":{"type":"string"},"payerAmount":{"type":"string"},"payerCurrencyCode":{"type":"string"},"feeFixed":{"type":"string","description":"Fixed fee component of the fee configuration stored on this transaction, in the transaction currency, at full stored precision. INFORMATIONAL - for reconciliation and for showing the merchant how the fee arose. Do not compute the fee from it: MAX(feeFixed, amount * feeRate) is the unrounded intermediate, and submitting that value at finalize is rejected with ERR_FEE_MISMATCH. The value to submit is `fee`."},"feeRate":{"type":"string","description":"Variable rate of the fee configuration stored on this transaction, at full stored precision - up to six decimal places, e.g. \"0.001250\" = 0.125%. Do not assume four: rounding a negotiated rate to four places produces a different fee from the one payware enforces. INFORMATIONAL, same as feeFixed."},"product":{"$ref":"#/components/schemas/ProductPresentationDTO"},"deliveryAddress":{"$ref":"#/components/schemas/DeliveryAddressDTO"},"recognition":{"$ref":"#/components/schemas/RecognitionDTO"}}},"BarcodeOptions":{"type":"object","properties":{"barFormat":{"type":"string"},"barModuleWidth":{"type":"string"},"barBarHeight":{"type":"string"},"barFontSize":{"type":"string"},"barHumanReadableLocation":{"type":"string"}}},"QrOptions":{"type":"object","properties":{"qrFormat":{"type":"string"},"qrErrorCorrection":{"type":"string"},"qrVersion":{"type":"string"},"qrBorder":{"type":"string"},"qrScale":{"type":"string"}}},"TransactionData":{"type":"object","properties":{"amount":{"type":"string"},"currency":{"type":"string"},"reasonL1":{"type":"string"},"reasonL2":{"type":"string"}}},"TransactionOptions":{"type":"object","properties":{"type":{"type":"string"},"timeToLive":{"type":"string"}}},"TransactionRequest":{"type":"object","properties":{"shippable":{"type":"boolean"},"deliveryAddress":{"$ref":"#/components/schemas/DeliveryAddressDTO"},"role":{"type":"string"},"paymentMethod":{"type":"string","description":"Payment method chosen by customer. Used by banks when processing transactions. A2A = direct transfer (lower fee, no rewards). CARD_FUNDED = card-linked account (higher fee, rewards eligible). BNPL = buy now pay later (installments). INSTANT_CREDIT = credit line approved at purchase.","enum":["A2A","CARD_FUNDED","BNPL","INSTANT_CREDIT"]},"producerPartnerId":{"type":"string","description":"partnerId of the POS terminal producer whose terminal produced this transaction. Must be a partner registered with payware and flagged as a producer; an unrecognised value is rejected. Determines the producer's revenue share and does NOT affect what the merchant is charged, which always follows the fee hierarchy. Omit it entirely when there is no producer. Not returned in any response."},"terminalId":{"maxLength":64,"minLength":0,"pattern":"^[^\\p{Cntrl}]*$","type":"string","description":"Opaque identifier of the physical terminal, scoped to the producer's own estate. payware assumes no format and enforces no uniqueness; it is recorded for provenance and never affects attribution or pricing."},"terminalManufacturer":{"maxLength":64,"minLength":0,"pattern":"^[^\\p{Cntrl}]*$","type":"string","description":"Device manufacturer as reported by the terminal. Recorded for provenance; a mismatch against the expected producer is surfaced in settlement review, never blocked."},"shop":{"type":"string"},"skipImageGeneration":{"type":"boolean"},"account":{"type":"string"},"friendlyName":{"type":"string"},"callbackUrl":{"type":"string"},"passbackParams":{"type":"string"},"trData":{"$ref":"#/components/schemas/TransactionData"},"trOptions":{"$ref":"#/components/schemas/TransactionOptions"},"qrOptions":{"$ref":"#/components/schemas/QrOptions"},"barOptions":{"$ref":"#/components/schemas/BarcodeOptions"},"vloginId":{"type":"string"}}},"TransactionResponse":{"type":"object","properties":{"transactionId":{"type":"string"},"imageData":{"type":"string"},"initiationMethod":{"type":"string"},"timeToLive":{"type":"integer","format":"int32"}}},"RecognitionFeedbackRequest":{"type":"object","properties":{"answer":{"type":"string","description":"CONFIRMED: the shopper said this is the ad. REJECTED: the shopper said it is not.","enum":["CONFIRMED","REJECTED"]}},"description":"The shopper's answer to a soundbite recognition."},"ProductData":{"type":"object","properties":{"type":{"type":"string"},"regularPrice":{"type":"string"},"currency":{"type":"string"},"overlapPriority":{"type":"string"},"activeFrom":{"type":"string"},"activeTo":{"type":"string"},"timeZone":{"type":"string"},"timeToLive":{"type":"string"}}},"ProductOptions":{"type":"object","properties":{"imageUrl":{"type":"string"},"termsUrl":{"type":"string"},"termsText":{"type":"string"}}},"ProductRequest":{"type":"object","properties":{"productId":{"type":"string"},"shop":{"type":"string"},"name":{"type":"string"},"shortDescription":{"type":"string"},"longDescription":{"type":"string"},"sku":{"type":"string"},"upc":{"type":"string"},"shippable":{"type":"string"},"quickPay":{"type":"string"},"active":{"type":"string"},"prData":{"$ref":"#/components/schemas/ProductData"},"prOptions":{"$ref":"#/components/schemas/ProductOptions"}}},"ProductDTO":{"type":"object","properties":{"productId":{"type":"string"},"type":{"type":"string"},"shopCode":{"type":"string"},"shopName":{"type":"string"},"name":{"type":"string"},"shortDescription":{"type":"string"},"longDescription":{"type":"string"},"sku":{"type":"string"},"upc":{"type":"string"},"currencyCode":{"type":"string"},"regularPrice":{"type":"string"},"salePrice":{"type":"string"},"overlapPriority":{"type":"string"},"timeToLive":{"type":"integer","format":"int32"},"shippable":{"type":"boolean"},"quickPay":{"type":"boolean"},"imageUrl":{"type":"string"},"termsUrl":{"type":"string"},"termsText":{"type":"string"},"deepLink":{"type":"string"},"activeFrom":{"type":"string","format":"date-time"},"activeFromZoned":{"type":"string"},"activeTo":{"type":"string","format":"date-time"},"activeToZoned":{"type":"string"},"timeZone":{"type":"string"},"active":{"type":"boolean"}}},"ImageRequest":{"type":"object","properties":{"type":{"type":"string"},"qrOptions":{"$ref":"#/components/schemas/QrOptions"},"barOptions":{"$ref":"#/components/schemas/BarcodeOptions"}}},"ImageResponse":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"format":{"type":"string"},"imageData":{"type":"string"}}},"POICreateRequest":{"required":["shopCode"],"type":"object","properties":{"shopCode":{"type":"string"},"name":{"maxLength":100,"minLength":0,"type":"string"},"ttlSeconds":{"maximum":600,"minimum":60,"type":"integer","format":"int32"},"callbackUrl":{"type":"string"}}},"POIResponse":{"type":"object","properties":{"isActive":{"type":"boolean"},"poiId":{"type":"string"},"shopCode":{"type":"string"},"shopName":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"pendingAmount":{"type":"number"},"pendingCurrency":{"type":"string"},"sessionToken":{"type":"string"},"sessionExpiresAt":{"type":"string","format":"date-time"},"ttlSeconds":{"type":"integer","format":"int32"},"callbackUrl":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"linkedVposCount":{"type":"integer","format":"int64"}}},"POIBatchCreateItem":{"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string"},"callbackUrl":{"maxLength":100,"minLength":0,"type":"string"},"ttlSeconds":{"maximum":600,"minimum":60,"type":"integer","format":"int32"}}},"POIBatchCreateRequest":{"required":["pois","shopCode"],"type":"object","properties":{"shopCode":{"type":"string"},"callbackUrl":{"maxLength":100,"minLength":0,"type":"string"},"ttlSeconds":{"maximum":600,"minimum":60,"type":"integer","format":"int32"},"pois":{"maxItems":50,"minItems":1,"type":"array","items":{"$ref":"#/components/schemas/POIBatchCreateItem"}}}},"POIBatchCreateResponse":{"type":"object","properties":{"created":{"type":"integer","format":"int32"},"pois":{"type":"array","items":{"$ref":"#/components/schemas/POIResponse"}}}},"CreateInvitationRequest":{"required":["email"],"type":"object","properties":{"email":{"maxLength":254,"minLength":0,"type":"string","description":"Merchant's email address. Determines invitation type: REGISTRATION for new emails, AUTHORIZATION_ONLY for existing merchants.","example":"merchant@example.com"},"phone":{"maxLength":20,"minLength":0,"type":"string","description":"Merchant's phone number","example":"+35912345678"},"contactName":{"maxLength":100,"minLength":0,"type":"string","description":"Merchant contact's first name","example":"John"},"contactSurname":{"maxLength":100,"minLength":0,"type":"string","description":"Merchant contact's surname","example":"Doe"},"companyName":{"maxLength":255,"minLength":0,"type":"string","description":"Company legal name","example":"ACME Corp Ltd"},"vatId":{"maxLength":50,"minLength":0,"type":"string","description":"VAT identification number","example":"BG123456789"},"registeredId":{"maxLength":50,"minLength":0,"type":"string","description":"Company registration ID (e.g. EIK in Bulgaria). When jurisdictionCode is BG, this triggers auto-population from the Bulgarian commercial registry.","example":"123456789"},"street":{"maxLength":255,"minLength":0,"type":"string","description":"Street address","example":"Main Street"},"streetNumber":{"maxLength":20,"minLength":0,"type":"string","description":"Street number","example":"10"},"zip":{"maxLength":20,"minLength":0,"type":"string","description":"ZIP / postal code","example":"1000"},"city":{"maxLength":100,"minLength":0,"type":"string","description":"City","example":"Sofia"},"legalFormId":{"type":"integer","description":"Legal form ID from reference data","format":"int32"},"businessActivityId":{"type":"integer","description":"Business activity ID from reference data","format":"int32"},"jurisdictionCode":{"maxLength":2,"minLength":0,"pattern":"^[a-zA-Z]{2}$","type":"string","description":"ISO 3166-1 alpha-2 country code","example":"BG"},"preferredLanguageCode":{"maxLength":5,"minLength":0,"pattern":"^[a-zA-Z]{2}([-_][a-zA-Z]{2})?$","type":"string","description":"Preferred language for the invitation (ISO 639-1)","example":"bg"}},"description":"Request to create a merchant invitation"},"CreateInvitationResponse":{"type":"object","properties":{"invitationId":{"type":"integer","description":"Unique invitation ID","format":"int32","example":42},"status":{"type":"string","description":"Invitation status","example":"PENDING","enum":["PENDING","COMPLETED","EXPIRED","CANCELLED"]},"type":{"type":"string","description":"Invitation type, auto-detected from email. REGISTRATION for new merchants, AUTHORIZATION_ONLY for existing ones.","example":"REGISTRATION","enum":["REGISTRATION","AUTHORIZATION_ONLY"]},"email":{"type":"string","description":"Merchant email address","example":"merchant@example.com"},"invitationLink":{"type":"string","description":"URL the merchant must visit to accept the invitation. The ISV is responsible for delivering this link to the merchant.","example":"https://my.payware.eu/invitation?t=abc123def456"},"expiresAt":{"type":"string","description":"Invitation expiry date","format":"date-time"}},"description":"Response after creating a merchant invitation"},"DataRetrievalRequest":{"required":["reportUnitId"],"type":"object","properties":{"reportUnitId":{"pattern":"^[A-Za-z0-9_-]{1,64}$","type":"string"},"ignorePagination":{"type":"boolean"},"locale":{"pattern":"^([a-zA-Z]{2})([_-][a-zA-Z]{2})?$","type":"string"},"dateFrom":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"},"dateTo":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"},"timeZone":{"maxLength":64,"minLength":0,"type":"string"}}},"AudioRequest":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"productId":{"type":"string"},"title":{"type":"string"},"folderId":{"type":"string"},"audioId":{"type":"string"},"status":{"type":"string"},"duration":{"type":"number","format":"double"},"uploadedAt":{"type":"string"}}},"TransactionStatusUpdateRequest":{"type":"object","properties":{"status":{"type":"string"},"statusMessage":{"type":"string"},"currency":{"type":"string"},"amount":{"type":"string"},"fee":{"type":"string"}}},"PlacementStatsDTO":{"type":"object","properties":{"from":{"type":"string","description":"UTC, ISO-8601","example":"2026-10-01T00:00:00Z"},"to":{"type":"string","description":"UTC, ISO-8601, exclusive","example":"2026-11-01T00:00:00Z"},"placements":{"type":"integer","description":"How many placements the figures cover (campaigns: the ones the caller can see)","format":"int32","example":3},"resolutions":{"type":"integer","description":"Offers shown when a bank resolved the placement id","format":"int64","example":1520},"recognitions":{"type":"integer","description":"Offers shown after a recognised soundbite tap","format":"int64","example":0},"transactions":{"type":"integer","description":"Payments started from the placement","format":"int64","example":212},"confirmedTransactions":{"type":"integer","description":"Of those, confirmed","format":"int64","example":198},"confirmedAmounts":{"type":"object","additionalProperties":{"type":"number","description":"Confirmed amounts by currency"},"description":"Confirmed amounts by currency","example":{"EUR":4180.5}}}},"AiringOccurrenceDTO":{"type":"object","properties":{"placementId":{"type":"string","example":"pl7e4rCToG"},"placementName":{"type":"string","description":"Calendar only"},"productId":{"type":"string","description":"Calendar only","example":"pr7e4rCToG"},"ruleId":{"type":"integer","format":"int32","example":17},"localDate":{"type":"string","description":"The local day the window starts on","example":"2026-10-25"},"startsAt":{"type":"string","description":"ISO-8601 with the zone's offset","example":"2026-10-25T08:00:00+02:00"},"endsAt":{"type":"string","description":"ISO-8601 with the zone's offset","example":"2026-10-25T08:30:00+02:00"}}},"ShopDTO":{"required":["code","name"],"type":"object","properties":{"isDefault":{"type":"boolean"},"id":{"type":"integer","format":"int32"},"name":{"maxLength":200,"minLength":0,"type":"string"},"code":{"maxLength":10,"minLength":0,"type":"string"},"labelUrl":{"maxLength":100,"minLength":0,"type":"string"},"ecommerce":{"type":"boolean"},"paymentProfileId":{"type":"integer","format":"int32"},"paymentProfileName":{"type":"string"},"merchantId":{"type":"integer","format":"int32"},"merchantName":{"type":"string"},"gps":{"maxLength":40,"minLength":0,"type":"string"},"country":{"type":"string"},"countryOverridden":{"type":"boolean"},"iconUrl":{"maxLength":150,"minLength":0,"type":"string"},"imageUrl":{"maxLength":150,"minLength":0,"type":"string"},"termsUrl":{"maxLength":150,"minLength":0,"type":"string"},"termsText":{"maxLength":3000,"minLength":0,"type":"string"},"preferredLanguageId":{"type":"integer","format":"int32"},"managedByIsvPartnerId":{"type":"string"},"managedByIsvName":{"type":"string"}}},"POIStatusResponse":{"type":"object","properties":{"poiId":{"type":"string"},"status":{"type":"string"},"pendingAmount":{"type":"number"},"pendingCurrency":{"type":"string"},"sessionToken":{"type":"string"},"sessionExpiresAt":{"type":"string","format":"date-time"},"transactionId":{"type":"string"},"transactionStatus":{"type":"string"},"lastTransactionId":{"type":"string"},"lastTransactionStatus":{"type":"string"}}},"LogEntry":{"type":"object","properties":{"@timestamp":{"type":"string","format":"date-time"},"logger_name":{"type":"string"},"thread_name":{"type":"string"},"stack_trace":{"type":"string"},"level":{"type":"string"},"message":{"type":"string"},"requestUri":{"type":"string"},"partnerId":{"type":"string"},"userEmail":{"type":"string"},"userId":{"type":"string"},"userName":{"type":"string"},"tenantType":{"type":"string"},"tenantId":{"type":"string"},"onBehalfOfPartnerId":{"type":"string"},"source":{"type":"string"}}},"LogQueryResponse":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/LogEntry"}},"totalCount":{"type":"integer","format":"int64"},"returnedCount":{"type":"integer","format":"int32"},"nextCursor":{"type":"string"},"hasMore":{"type":"boolean"}}},"LogStatusResponse":{"type":"object","properties":{"partnerId":{"type":"string"},"logsAvailable":{"type":"boolean"},"totalSizeBytes":{"type":"integer","format":"int64"},"fileCount":{"type":"integer","format":"int32"}}},"LegalFormDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"code":{"type":"string"},"acronym":{"type":"string"},"extensiveTitle":{"type":"string"}}},"LanguageDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"code":{"type":"string"},"nativeName":{"type":"string"}}},"JurisdictionDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"officialName":{"type":"string"},"code":{"type":"string"},"phoneCode":{"type":"string"},"languageId":{"type":"integer","format":"int32"}}},"CurrencyDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"code":{"type":"string"}}},"BusinessActivityDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"section":{"type":"string"},"activityDescription":{"type":"string"}}},"InvitationListItem":{"type":"object","properties":{"invitationId":{"type":"integer","description":"Unique invitation ID","format":"int32"},"email":{"type":"string","description":"Merchant email address"},"companyName":{"type":"string","description":"Company name (if provided)"},"type":{"type":"string","description":"Invitation type","enum":["REGISTRATION","AUTHORIZATION_ONLY"]},"status":{"type":"string","description":"Current status","enum":["PENDING","COMPLETED","EXPIRED","CANCELLED"]},"createdAt":{"type":"string","description":"When the invitation was created","format":"date-time"},"expiresAt":{"type":"string","description":"When the invitation expires","format":"date-time"},"completedAt":{"type":"string","description":"When the invitation was completed (null if not completed)","format":"date-time"},"merchantPartnerId":{"type":"string","description":"Partner ID of the merchant created or authorized by this invitation. For AUTHORIZATION_ONLY invitations, populated immediately. For REGISTRATION invitations, populated after completion."}},"description":"Summary view of an invitation for list display"},"PageInvitationListItem":{"type":"object","properties":{"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/InvitationListItem"}},"number":{"type":"integer","format":"int32"},"sort":{"$ref":"#/components/schemas/SortObject"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"empty":{"type":"boolean"}}},"PageableObject":{"type":"object","properties":{"offset":{"type":"integer","format":"int64"},"sort":{"$ref":"#/components/schemas/SortObject"},"paged":{"type":"boolean"},"pageNumber":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"unpaged":{"type":"boolean"}}},"SortObject":{"type":"object","properties":{"empty":{"type":"boolean"},"sorted":{"type":"boolean"},"unsorted":{"type":"boolean"}}},"InvitationDetailResponse":{"type":"object","properties":{"invitationId":{"type":"integer","description":"Unique invitation ID","format":"int32"},"type":{"type":"string","description":"Invitation type","enum":["REGISTRATION","AUTHORIZATION_ONLY"]},"status":{"type":"string","description":"Current status","enum":["PENDING","COMPLETED","EXPIRED","CANCELLED"]},"email":{"type":"string","description":"Merchant email address"},"phone":{"type":"string","description":"Merchant phone number"},"contactName":{"type":"string","description":"Contact first name"},"contactSurname":{"type":"string","description":"Contact surname"},"companyName":{"type":"string","description":"Company legal name"},"vatId":{"type":"string","description":"VAT identification number"},"registeredId":{"type":"string","description":"Company registration ID"},"street":{"type":"string","description":"Street address"},"streetNumber":{"type":"string","description":"Street number"},"zip":{"type":"string","description":"ZIP / postal code"},"city":{"type":"string","description":"City"},"legalFormId":{"type":"integer","description":"Legal form ID","format":"int32"},"businessActivityId":{"type":"integer","description":"Business activity ID","format":"int32"},"jurisdictionCode":{"type":"string","description":"ISO 3166-1 alpha-2 country code"},"resendCount":{"type":"integer","description":"Number of times the invitation email was resent (portal only)","format":"int32"},"createdAt":{"type":"string","description":"When the invitation was created","format":"date-time"},"expiresAt":{"type":"string","description":"When the invitation expires","format":"date-time"},"completedAt":{"type":"string","description":"When the invitation was completed","format":"date-time"},"merchantPartnerId":{"type":"string","description":"Partner ID of the associated merchant. For AUTHORIZATION_ONLY invitations, populated immediately. For REGISTRATION invitations, populated after completion."},"assignedShopCode":{"type":"string"}},"description":"Full details of an invitation"},"ConsentCheckbox":{"type":"object","properties":{"id":{"type":"string","description":"Checkbox identifier","example":"isv_authorization"},"required":{"type":"boolean","description":"Whether this checkbox is required","example":true},"label":{"type":"string","description":"Localized checkbox label text. Contains {isvName} and/or {companyName} placeholders that the ISV must replace before displaying to the merchant. May contain HTML anchor tags for legal document links."}},"description":"Consent checkboxes to display. All are required."},"ConsentConfigResponse":{"type":"object","properties":{"effectiveDate":{"type":"string","description":"T&C effective date (YYYY-MM-DD). Must be included in consent data when registering merchants.","example":"2025-01-15"},"checkboxes":{"type":"array","description":"Consent checkboxes to display. All are required.","items":{"$ref":"#/components/schemas/ConsentCheckbox"}},"plans":{"type":"array","description":"Available plan options for merchant registration","items":{"$ref":"#/components/schemas/PlanOption"}},"pricingUrl":{"type":"string","description":"URL to the pricing page (localized by language)","example":"https://payware.eu/en/pricing"}},"description":"Consent configuration for merchant registration. Contains checkbox labels (localized), plan options, and the T&C effective date. Labels contain placeholder tokens that must be replaced by the ISV before display."},"PlanOption":{"type":"object","properties":{"code":{"type":"string","description":"Plan code to send in registration request. null for 'Activate Later'.","nullable":true,"example":"STD"},"name":{"type":"string","description":"Localized plan name","example":"Standard Plan"},"description":{"type":"string","description":"Localized plan description","example":"Full features for growing businesses"},"recommended":{"type":"boolean","description":"Whether this plan is recommended","example":false}},"description":"Available plan options for merchant registration"},"ReportRequestDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"updated":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"requestStatus":{"type":"string"},"exportId":{"type":"string"},"exportStatus":{"type":"string"},"contentType":{"type":"string"},"fileName":{"type":"string"},"outputFinal":{"type":"boolean"},"partnerId":{"type":"string"},"dateFrom":{"type":"string","format":"date-time"},"dateTo":{"type":"string","format":"date-time"},"ignorePagination":{"type":"boolean"},"pages":{"type":"string"}}},"ReportDTO":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"version":{"type":"string"},"defaultFormat":{"type":"string"},"clientVisible":{"type":"boolean"},"path":{"type":"string"},"parameters":{"type":"boolean"},"merchantVisible":{"type":"boolean"},"isvVisible":{"type":"boolean"},"bankVisible":{"type":"boolean"},"plan":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"}}}},"securitySchemes":{"bearerAuth":{"type":"http","description":"JWT token authentication","scheme":"bearer","bearerFormat":"JWT"},"apiKeyAuth":{"type":"apiKey","description":"API version header","name":"api-version","in":"header"}}}}