# Paydro complete integration documentation Generated from the public goal guides and developer Markdown sources. API calls require the organizer/company origin described below. Source: https://developer.paydro.com/llm/summary.md # Paydro: start here Paydro helps organizers sell tickets, collect registrations and manage events and attendees. Choose the goal below, then read its guide and only the reference material needed for the task. ## Access and supported approaches - Public shop links, buttons and iframes need no organizer API credentials. Organizer API calls use the organization's HTTPS origin and authorized HTTP Basic credentials kept server-side. - The developer host serves documentation, not account API requests. Event UUIDs and public shop slugs are different identifiers. Local `https://developer.test.test` is a development origin, not a public sandbox. - Public API-key issuance, Paydro OAuth client registration and registration webhook subscriptions are not offered by the current documentation. Some workflows require organizer UI steps; do not invent endpoints. - Establish organization, role and affected records. Read current capabilities before writing; inspect response bodies and verify outcomes before retrying uncertain writes. Respect the request's scope for publication, messages and financial changes. ## Interpret the request - **Ticket / attendee / order:** entitlement, individual registration and payer-level booking. An invitation is an offer, not necessarily a reservation or completed registration. - **Cancel / refund:** distinguish invalidating admission, correcting a price, creating a credit document and returning money. - **Invoice / paid / payout:** distinguish an invoice after online payment, pay-later registration, a credit document and organizer settlement. Customer payment, provider payout and Paydro settlement are separate facts. - **Limit / closed:** distinguish code uses, quantity per order, cumulative product allocation, stock and expiry; sales closure is not financial settlement. Resolve ambiguity that changes the action. Historical support workarounds and account-specific exceptions do not establish current product behavior. ## Choose a goal For website ticket sales, follow the conversation in the selling guide: ask for a missing shop link, then the widget choice, before generating code. Respect plan-only and no-file-change requests. - [Sell tickets on my website](https://developer.paydro.com/llm/sell-tickets.md) - [Use an existing shop link](https://developer.paydro.com/llm/use-shop-link.md) - [Find my shop link in Paydro](https://developer.paydro.com/llm/find-shop-link.md) - [Create a ticket shop for my website](https://developer.paydro.com/llm/create-ticket-shop.md) - [Create a Paydro account](https://developer.paydro.com/llm/create-paydro-account.md) - [Show our events](https://developer.paydro.com/llm/show-events.md) - [Set up an event](https://developer.paydro.com/llm/set-up-event.md) - [Manage ticket options](https://developer.paydro.com/llm/manage-tickets.md) - [Collect attendee information](https://developer.paydro.com/llm/collect-attendee-information.md) - [Match our branding and language](https://developer.paydro.com/llm/branding-and-language.md) - [Manage guest registrations](https://developer.paydro.com/llm/guest-registrations.md) - [Help customers with bookings](https://developer.paydro.com/llm/help-with-bookings.md) - [Handle cancellations and refunds](https://developer.paydro.com/llm/cancellations-and-refunds.md) - [Communicate with attendees](https://developer.paydro.com/llm/communicate-with-attendees.md) - [Connect our other tools](https://developer.paydro.com/llm/connect-other-tools.md) - [Understand event performance](https://developer.paydro.com/llm/event-performance.md) - [Accept invoice payments](https://developer.paydro.com/llm/accept-invoice-payments.md) - [Configure payment providers](https://developer.paydro.com/llm/configure-payment-providers.md) - [Understand payouts and settlement](https://developer.paydro.com/llm/understand-payouts.md) - [Prepare financial records](https://developer.paydro.com/llm/financial-records.md) - [Manage entry at the event](https://developer.paydro.com/llm/manage-entry.md) - [Fix and verify an integration](https://developer.paydro.com/llm/fix-integration.md) ## Broader documentation - [API basics](https://developer.paydro.com/en-us/docs/api-basics.md), [authentication](https://developer.paydro.com/en-us/docs/authentication.md) and [permissions](https://developer.paydro.com/en-us/docs/permissions.md). - [API coverage and limits](https://developer.paydro.com/en-us/docs/api-coverage.md), [OpenAPI contract](https://developer.paydro.com/openapi/v2.json) and [all guides](https://developer.paydro.com/llms.txt). Every developer guide is available as `/en-us/docs/.md`; use the published contract for fields and response shapes. ## Completion Verify the outcome with an authorized test setup; explain remaining UI steps or unsupported capabilities. Keep personal data, credentials and private download URLs out of public output. --- Source: https://developer.paydro.com/llm/accept-invoice-payments.md # Accept invoice payments Allow eligible customers to register now and pay later, while preserving the intended ticket-delivery and reconciliation rules. Start with [summary](https://developer.paydro.com/llm/summary.md); distinguish receiving an invoice after online payment from choosing invoice payment. ## Determine the intended outcome Establish whether invoice payment is available to everyone or only selected customers, who pays for a group booking, and whether tickets may be sent before payment. Confirm the event, currency and organizer's payment instructions. ## Configure the registration workflow 1. Inspect the current event invoice settings in the organizer UI. Use only documented writable fields when integrating through the API. 2. For general availability, configure the event's invoice-payment option. For selected customers, keep ordinary checkout online-only and configure an eligible promo code with invoice allowance. 3. Check country restrictions and the invoice minimum as well as the promo. A promo exception does not bypass those checks; the order total must be strictly above a configured minimum, not equal to it. 4. For a group purchase, collect billing details once at order level and attendee details per ticket. Several attendees can belong to one order and invoice; the payer need not be an attendee. 5. Review the bank/payment instructions, purchase reference and invoice preview. If invoice payment is configured as online-only, bank details are not shown on the invoice. 6. Review the setting labelled “Send tickets along with unpaid invoice”. Configure it for the intended release policy and verify the unpaid and paid paths separately. 7. Test both ordinary checkout and the promo-exception checkout in an authorized test setup. Confirm that granting an exception did not make invoice payment generally available. ## Reconcile and follow up For a bank transfer, establish actual receipt through authorized financial records before marking an invoice paid. Read the current order capabilities, then use the documented mark-paid action only when allowed and requested. This records an invoice payment; it does not force an online payment-provider transaction to succeed. Re-read the order and inspect ticket availability, queued messages and reminder eligibility separately. Check current payment terms and reminder settings; do not promise a fixed reminder weekday or cadence from historical advice. ## Consequences and common misunderstandings - An online-paid order can still have an invoice. “Needs an invoice” does not necessarily mean “needs to pay later”. - Changing attendee details does not necessarily change the payer or billing address. - A payment reference printed on an invoice does not guarantee that a bank-transfer payer includes it. - Merely enabling a payment option is not proof that every order meets its amount, country and lifecycle rules. - Cancelling an unpaid invoice is distinct from returning money; use [cancellation guidance](https://developer.paydro.com/llm/cancellations-and-refunds.md). ## Verify Check a multi-attendee order, an ineligible country/amount, the ordinary online-only path and the permitted exception. Verify payment state and actual delivery evidence before reporting tickets as sent or money as received. ## Related guidance - [Guest registrations and promo limits](https://developer.paydro.com/llm/guest-registrations.md) - [Order management and marking paid](https://developer.paydro.com/en-us/docs/order-management.md) - [Events and writable fields](https://developer.paydro.com/en-us/docs/events.md) - [Communicate with attendees](https://developer.paydro.com/llm/communicate-with-attendees.md) --- Source: https://developer.paydro.com/llm/branding-and-language.md # Match our branding and language Adapt the website button and embedded shop using supported presentation controls. Start with [website registration](https://developer.paydro.com/llm/sell-tickets.md) and the organizer `/{event_id}/widgets/index` generator. ## Button controls The generator exports an anchor plus a standalone `/css/button.css` stylesheet; retain both. - Label: editable text, escaped as HTML; use a meaningful action in the site's language. - Background: palette name plus shade `400`, `600` or `900` (light, mid or dark). - Palette: `stone`, `olive`, `yellow`, `teal`, `indigo`, `rose`, `neutral`, `mist`, `amber`, `emerald`, `blue`, `pink`. - Palette continued: `zinc`, `mauve`, `orange`, `green`, `sky`, `fuchsia`, `slate`, `taupe`, `red`, `lime`, `cyan`, `violet`. - Text colour: `text-black/80` or `text-white/80`. - Text size: `text-xs`, `text-sm`, `text-base`, `text-lg` or `text-xl`. - Weight: optional `font-semibold`. - Corners: `rounded-sm`, `rounded-md`, `rounded-lg`, `rounded-xl`, `rounded-2xl` or `rounded-full`. - Padding pairs: `px-4 py-2`, `px-6 py-4` or `px-8 py-6`. - Icon: none or an inline SVG from the generator; keep its `button-icon` class and generated layout classes. Keep the base `button` class; preview background is an editor setting, not an exported page background. Choose only stylesheet-supported classes or use the destination site's own button styles. ## Embedded shop Use the generator switches for `image`, `info`, `title`, `date` and `location`. Unchecked options become query parameters such as `image=false`; enabled options are omitted. The date switch is available only when the shop is configured to show dates. The containing site's CSS cannot style the inside of a cross-origin iframe. Use Paydro's organizer shop-design settings for internal styling; do not invent theme query parameters. ## Language Translate surrounding website copy and the button label to match the visitor's language. Inspect the event's available shop-language settings and actual generated/published links. Do not assume translating the button changes checkout language or invent a locale URL parameter. If the requested language cannot be configured, explain that limit and preserve a working registration link. ## Verify Check contrast, keyboard focus, label wrapping, mobile layout and every configured shop language. Confirm hidden sections and event dates behave as intended in the embedded shop. ## More documentation - [Embed guide](https://developer.paydro.com/en-us/docs/embed-ticket-shop.md) - [Workflow limits](https://developer.paydro.com/en-us/docs/api-coverage.md) --- Source: https://developer.paydro.com/llm/cancellations-and-refunds.md # Handle cancellations and refunds Determine whether a booking can be cancelled and whether money must be returned. Start with [summary](https://developer.paydro.com/llm/summary.md); establish the event, order, affected tickets and intended outcome. ## Determine the intended outcome Resolve which tickets must remain valid, which must be invalidated and the intended amount to return. Identify online payment, an unpaid invoice, an offline-paid invoice or a reservation before choosing an action. | Intent | How to approach it | | --- | --- | | Cancel the entire booking | Review all affected tickets and any required provider refund before cancellation. | | Cancel one ticket | Use the selected-attendee organizer refund workflow; verify the other tickets remain valid. | | Reduce the price but retain admission | Use the organizer price-correction flow without selecting the ticket for removal; inspect the resulting refund preview. | | Cancel an unpaid invoice | Use the current cancellation capability; do not describe an unpaid amount as money being returned. | | Cancel but retain the payment | Proceed only if the supported organizer preview expresses the intended cancellation and zero refund; otherwise explain the remaining organizer/support step. | For a price-only correction, enter the intended remaining price, not the amount to refund. For example, reducing a synthetic ticket from 120 to 90 implies a 30 price difference before any separately applicable fee/tax adjustments. Ticket removal is a different selection: combining it with a price edit can cancel admission instead of retaining it. Check the full preview, including other tickets of the same product, rather than assuming a price edit affects only one person. ## Workflow 1. GET `/{event_id}/orders/detail_data/{order_id}.json` for current payment capabilities and pending actions. 2. Distinguish reservation release, order cancellation and payment-provider refund. 3. For an eligible reservation release, use POST `/{event_id}/orders/drop_reservation/{order_id}.json`. 4. For eligible order cancellation, use PUT `/{event_id}/orders/cancel/{order_id}.json`. 5. Inspect the response body even on HTTP 200; `provider_refund_required` means the refund flow is needed first. 6. Use the organizer refund UI for provider refunds or selected-attendee refunds. 7. Review its selections, amount and confirmation, then follow the resulting operation status. 8. Re-read the booking and distinguish cancellation status from refund settlement in the result. ## Boundaries `orders/cancel_refund` and `refund_attendees` are stateful organizer workflows, not a published single-call refund API. Cancellation can create credit invoices and notifications; account for those effects. Never report “refunded” solely because a cancellation succeeded or a refund was requested. After a timeout, inspect the current order/provider operation before repeating any financial action. Use an approved payment test setup for verification; synthetic names alone do not prevent real charges or refunds. ## Consequences and common misunderstandings Cancellation can release capacity, making tickets available for sale again; check stock, visibility and waiting-list policy. A price-only refund does not change the ticket type; follow [booking changes](https://developer.paydro.com/llm/help-with-bookings.md) if the entitlement must also change. A credit document is not proof of a completed bank transfer, including when the original invoice was paid outside the provider. For pending refunds, inspect the actual operation: provider processing, insufficient balance and failed authorization require different remedies. Do not promise a fixed refund duration, substitute a different bank account or introduce an administration fee merely as a workaround for an unclear request. ## Verify Check affected tickets, final order state, credit documents and separately verified payment outcome. If the remaining step requires organizer interaction, state that clearly instead of inventing an API call. ## More documentation - [Order management](https://developer.paydro.com/en-us/docs/order-management.md) - [Workflow limits](https://developer.paydro.com/en-us/docs/api-coverage.md) - [Testing](https://developer.paydro.com/en-us/docs/testing.md) --- Source: https://developer.paydro.com/llm/collect-attendee-information.md # Collect attendee information Add registration questions such as company names, dietary requirements or session preferences. Start with [summary](https://developer.paydro.com/llm/summary.md); identify which ticket categories need each question. ## Determine the question scope Use per-ticket/category questions for information that can differ by participant, such as a workshop or dietary preference. Use order-level questions for shared booking information; an order is not necessarily one attendee. Category definitions can apply to several products, so inspect that scope before changing a question. For two people in one order, verify that each can provide a different answer where required. Distinguish a standard billing-company field from a custom attendee-company question, including which field an export or badge uses. Choose workshop questions when session capacity matters; do not assume a plain choice field enforces capacity. For multiple rounds, define and verify each required session choice. Do not promise ranked preference allocation without a documented supported workflow. Check required state and self-service editability independently. ## Workflow 1. GET `/{event_id}/categories/index.json` to read categories and question definitions. 2. Choose a documented question type and valid options; distinguish required from optional answers. 3. PUT `/{event_id}/category_fields/edit/{category_id}.json` to create a `CategoryField` definition. 4. Re-read category definitions to obtain the new UUID; creation can succeed with a legacy redirect. 5. PUT `/{event_id}/category_fields/edit/{category_id}/{question_id}.json` to edit an existing definition. 6. Test the question in the public registration flow for each relevant ticket. 7. Read attendee detail to retrieve answers and their current or historical definitions. ## Existing registrations Purchased tickets retain question snapshots; changing a definition does not automatically update them. Use the documented snapshot refresh or attendee-question actions only when that change is intended. The category-wide refresh can partially succeed; inspect failed IDs before recovery. Attendee answer updates use question UUIDs inside `OrderLine`, not labels as field names. Validate choices against returned definitions; file answers are not supported by the attendee save path. ## Consequences of changing a live question Renaming or removing answer options is not merely a label change when existing answers contain the old values. Read current definitions and purchased snapshots, inspect existing answers, and decide explicitly whether older registrations should be migrated. A category-wide refresh can affect more than the one edited definition; review its documented scope before applying it. Verify that older answers remain interpretable and workshop capacity remains consistent after an intended refresh. Do not infer an option-count limit from an unanswered support question or a UI problem. ## Verify Test required fields, optional blanks and each chosen answer type using synthetic registrations. Check that older answers remain interpretable after a question or option changes. Collect only information needed for the event and restrict access to personal answers. ## More documentation - [Question definitions](https://developer.paydro.com/en-us/docs/ticket-questions.md) - [Question types and answers](https://developer.paydro.com/en-us/docs/question-types.md) - [Attendee management](https://developer.paydro.com/en-us/docs/attendee-management.md) --- Source: https://developer.paydro.com/llm/communicate-with-attendees.md # Communicate with attendees Deliver the right event information, invitations or existing booking documents to the intended recipients. Start with [summary](https://developer.paydro.com/llm/summary.md); identify the audience, message type and whether the request includes sending. ## Choose the workflow - Ticket resend: POST `/{event_id}/order_lines/resend_one_ticket/{attendee_id}.json`. - Invoice/order resend: PUT `/{event_id}/orders/resend/{order_id}.json`. - Reservation resend: PUT `/{event_id}/orders/resend_reservation/{order_id}.json`. - Promo invitation: use the documented promo-code invitation workflow and per-recipient results. - General announcements: use the organizer's available communication tools or a connected mailing service. There is no documented general arbitrary-message API; a ticket resend does not send custom announcement text. ## Templates, audiences and files Choose a confirmation-template change for future registrations, or a separate announcement for existing attendees. A custom template body replaces the default text; preserve the required personalization/link fields supplied by the editor. Preview each relevant message type rather than assuming online-paid, invoice and free-order confirmations share one template. An order can contain several tickets: do not insert one attendee's ticket name as if it described the entire order. Verify billing/order recipients separately from attendee recipients, and inspect organizer notification-copy settings separately. The event's contact-copy setting and individual follower notifications are different controls. For a programme or other file, use supported event-file upload and link to it in the message; do not assume arbitrary email attachments are supported. File management requires its documented administrator permission. Download links can grant access without login, so distribute private files only to their intended audience. Template editing, file uploading and sending are separate actions; changing a template does not resend previous confirmations. ## Workflow 1. Read the relevant attendee/order state and verify event ownership and recipient details. 2. For announcements, prepare the message and select the intended event audience through supported tools. 3. For Mailchimp, verify the connected account, audience and event-specific synchronization settings. 4. Preserve consent and unsubscribe states when using marketing workflows. 5. Perform the requested delivery action once and inspect the actual success or partial-failure response. 6. Track queue acceptance separately from delivery; inspect available mail-delivery information when troubleshooting. ## Limits Company clearance, lifecycle rules and invitation allowances can restrict sends. Never retry an uncertain send blindly; check history and retry only recipients known to have failed. A draft-only request is complete with a draft; do not turn it into a send. Avoid including private attendee lists or bearer document links in public messages or logs. ## Common misunderstandings A successful registration screen does not prove the confirmation was delivered. Inspect recipient, queue and delivery information before changing registration data to solve a mail problem. Do not ban punctuation in an organizer name based on a historical mail-formatting workaround; diagnose the current sender-formatting error. Do not infer attachment contents from the resend button label; verify the selected message type and resulting documents. ## Verify Test formatting and recipient selection with an authorized synthetic recipient before enabling a new workflow. Report what was drafted, queued, delivered or still unverified using the available evidence. ## More documentation - [Mailchimp](https://developer.paydro.com/en-us/docs/mailchimp.md) - [Promo invitations](https://developer.paydro.com/en-us/docs/promo-codes.md) - [Order messages](https://developer.paydro.com/en-us/docs/order-management.md) --- Source: https://developer.paydro.com/llm/configure-payment-providers.md # Configure payment providers Help an authorized organizer establish working payment collection and diagnose connection problems. Start with [summary](https://developer.paydro.com/llm/summary.md); confirm the organization, event and intended collection account. Use the organizer provider setup UI; its provider authorization callbacks are not a public Paydro configuration API. ## Determine the intended outcome Distinguish first-time setup, a disabled payment method, expired authorization, changing the default provider and changing the handling of an event with existing payments. Establish whether historical refunds are still needed. Provider management requires organization-administrator rights; event access alone is insufficient. ## Workflow 1. Confirm the selected organization and rights before opening provider settings. A similarly named event in another organization can have a different setup. 2. Inspect the available collection options and choose the intended account through the supported organizer flow. Do not assume platform-managed collection is available to every account. 3. Confirm connection authorization, the selected provider profile/account and enabled payment methods separately. “Connected” alone does not establish checkout readiness. 4. Review the event configuration and run an authorized payment test through the intended shop path before declaring it ready for sales. 5. For revoked authorization or an invalid-grant error, identify the affected connection and use the supported reconnection/recovery flow. Do not repeatedly retry unchanged credentials. 6. Before switching or disconnecting, inspect existing event payments, pending operations and the original provider identity needed for later refunds. Check what the current UI permits for that event. 7. Re-read configuration after changes and verify future checkout separately from historical payment/refund access. ## Consequences and common misunderstandings - An organization's new default does not establish that existing events or payments have moved to the new account. - Disconnecting credentials can prevent access to old transactions. Do not treat provider removal as a harmless cleanup action. - A duplicated event needs destination-organization validation; do not assume the source account's connection is available there. - Public payment-method icons and a successful connection are not evidence that each advertised method is enabled at the provider. - Support-assisted exceptions in historical conversations are not general switching permissions. - Provider fees, Paydro fees and payout timing are separate concerns. Use the applicable account configuration and records rather than historical price estimates. ## Verify Test the intended method in the approved provider test setup; synthetic attendee data alone does not prevent real charges. Confirm the event and collection account without copying tokens, bank details or customer references into reports. If the remaining step requires an administrator or provider-side action, state the specific missing step. ## Related guidance - [Understand payouts](https://developer.paydro.com/llm/understand-payouts.md) - [Handle cancellations and refunds](https://developer.paydro.com/llm/cancellations-and-refunds.md) - [Permissions](https://developer.paydro.com/en-us/docs/permissions.md) - [Fix and verify an integration](https://developer.paydro.com/llm/fix-integration.md) - [Testing](https://developer.paydro.com/en-us/docs/testing.md) --- Source: https://developer.paydro.com/llm/connect-other-tools.md # Connect our other tools Keep a CRM, mailing platform or internal application aligned with Paydro registrations. Start with [summary](https://developer.paydro.com/llm/summary.md); define the destination, event scope, fields and desired update frequency. ## Choose a connection Check the existing HubSpot or Mailchimp organizer integration before building a custom connector. Their provider OAuth callbacks are not a public Paydro OAuth or webhook-subscription service. For custom synchronization, authenticate on your server and use documented reads and snapshot/change resources. ## Custom synchronization 1. Import `/orders/all_data.json` or `/{event_id}/order_lines/all_data/2.json` for the required scope. 2. Parse the documented compact shape and retain event, order, attendee and product UUID relationships. 3. Upsert destination records by stable IDs; avoid using email as the registration's unique key. 4. Poll the matching `changed_data` resource and apply `deleted_items` by ID. 5. Commit each successful local import before advancing your own synchronization state. 6. Keep ETags scoped to origin, credentials and exact URL; a 304 keeps the previous payload. 7. Recover from a missed weekly window with a fresh import and periodically reconcile a full paginated view. ## Limits Changes start at Sunday midnight in the server timezone; there is no durable arbitrary “since” cursor. Bulk orders have a 75,000 combined-row cap; event attendee snapshots have a 10,000-row cap. Company attendee snapshots cover events starting within two years; use event scope for older events. Deletion tracking is time-limited; absence from a capped snapshot is not proof of deletion. No public webhook-subscription API is documented. Do not treat payment callbacks or stage SSE as registration webhooks. ## Verify Exercise duplicate imports, edited answers, cancellation/deletion, a weekly rollover and recovery from downtime. Keep personal fields minimal and preserve the destination's consent/unsubscribe state. ## More documentation - [Synchronization](https://developer.paydro.com/en-us/docs/synchronizing-data.md) - [Pagination and limits](https://developer.paydro.com/en-us/docs/pagination-and-filtering.md) - [HubSpot](https://developer.paydro.com/en-us/docs/hubspot.md) / [Mailchimp](https://developer.paydro.com/en-us/docs/mailchimp.md) --- Source: https://developer.paydro.com/llm/create-paydro-account.md # Create a Paydro account Use this path when the user needs an account before [creating a ticket shop](https://developer.paydro.com/llm/create-ticket-shop.md). ## Offer the next step Point to [Paydro signup](https://paydro.com/en-us/signup). Ask: “Would you like to sign up in Paydro yourself, or have me help you through signup in your browser?” Do not ask again if they already chose. With browser tools and the user's request to assist, open signup, inspect the current form and help with the required information. Do not invent fields or claim that reading this guide grants account access. Without browser tools, provide the signup link and ask the user to return once they have signed in. Keep passwords and verification codes out of chat; let the user enter them directly in Paydro. Let the user handle identity verification and acceptance of terms or commitments when required. There is no documented public account-creation API in these guides. Do not simulate signup with invented endpoints. ## Continue after signup Verify that the user can access the intended organizer account; do not treat submitting a signup form as proof that setup is complete. Continue with [create a ticket shop](https://developer.paydro.com/llm/create-ticket-shop.md), then [widget selection and integration code](https://developer.paydro.com/llm/use-shop-link.md). If signup is blocked, report the current step and what the user must do next. Do not invent a shop URL or generate supposedly ready-to-use code without one. --- Source: https://developer.paydro.com/llm/create-ticket-shop.md # Create a ticket shop for website registration Use this path when the user wants a new shop before [adding it to their website](https://developer.paydro.com/llm/sell-tickets.md). If they have no Paydro account, start with [create an account](https://developer.paydro.com/llm/create-paydro-account.md). ## Gather details in small steps Use details already supplied. First ask for the event name, date/time with timezone, and location or online format. Next ask for ticket types, prices/currency and capacity. Confirm the intended organizer if the account has more than one organization. Explain the concrete next step: create a draft shop, configure tickets, review it, then choose the website widget. ## Create with available access When the user asks you to create the shop and authorized browser access is available, use the organizer UI and inspect its current fields and results. If authorized organizer API access is already configured, follow [set up an event](https://developer.paydro.com/llm/set-up-event.md) and [manage ticket options](https://developer.paydro.com/llm/manage-tickets.md), reading the documented fields before writes. Never invent a public account-creation API or request organizer credentials for frontend code. Without supported account access, guide the user through creating the event and tickets in Paydro; state that you cannot create it directly in this session. Check for an existing matching draft before retrying an uncertain creation. Verify the event and ticket settings after saving. ## Review and return to integration Creation is separate from opening sales. Keep the shop a draft unless publication is within the user's request; review payment readiness and event details before opening it. Report the actual created event and its status, or the precise remaining step if creation is incomplete. Do not claim sales are open from a saved draft alone. Obtain the ordinary public shop link from the event's Widgets page (or documented `direct_link` response). Continue with [widget selection and code generation](https://developer.paydro.com/llm/use-shop-link.md), carrying forward all known choices. Identify any publication or payment setup still needed before live sales. --- Source: https://developer.paydro.com/llm/event-performance.md # Understand event performance Report sales, registrations or attendance and compare equivalent events or periods. Start with [summary](https://developer.paydro.com/llm/summary.md); agree the metric, date range, timezone and comparison basis. ## Workflow 1. Discover the relevant events, explicitly requesting older years where needed. 2. Retrieve all required pages of orders and attendees, keeping their event relationships. 3. Use order `payment_state` and `is_paid` to separate paid sales from reservations and pending payments. 4. Define whether ticket counts include cancellations, free tickets, packages or invited guests. 5. Calculate monetary totals using documented fields and decimal-safe arithmetic per event currency. 6. Use attendee scan state for attendance; an order is not a headcount. 7. For website traffic, GET `/{event_id}/traffic_logs/index.json` and use its documented aggregates. 8. Present the reporting scope, retrieval time, definitions and any incomplete coverage alongside the result. ## Interpretation Do not sum different currencies without an explicitly chosen conversion method. Distinguish gross sales, refunds, invoiced amounts and cash received; one field is not all four metrics. Compare equivalent sales periods and account for moved event dates and different capacities. The traffic projection provides recent totals and top sources/cities, not arbitrary date-range analytics. Traffic totals alone do not establish ticket-sale attribution or a trustworthy conversion rate. ## Verify Reconcile a small sample and totals against the organizer view for the same scope and statuses. Check pagination, empty events, pending payments and cancellations before relying on the comparison. Keep individual attendee and visit data private; prefer aggregated reporting. ## More documentation - [Orders](https://developer.paydro.com/en-us/docs/orders.md) - [Analytics](https://developer.paydro.com/en-us/docs/analytics.md) - [Data types](https://developer.paydro.com/en-us/docs/data-types.md) --- Source: https://developer.paydro.com/llm/financial-records.md # Prepare financial records Collect orders, invoices and supporting exports for bookkeeping or reconciliation. Start with [summary](https://developer.paydro.com/llm/summary.md); establish the organization, events, period and required accounting format. ## Workflow 1. Retrieve the relevant paginated orders or use documented event exports. 2. GET `/{event_id}/orders/export_to/csv` or `/{event_id}/orders/exportexcel` for file exports. 3. Read individual order details when payment state, line items or document references are needed. 4. Download eligible invoices using `/{event_id}/orders/download_invoice/{order_id}`. 5. Preserve order/event IDs, document references, currency and original monetary precision. 6. Separate paid amounts, outstanding invoices, refunds and cancellations according to their actual states. 7. Map documented fields into the accounting system and reconcile totals before importing. ## Limits and handling File downloads return binary or CSV content, not the ordinary JSON envelope; validate status and content type. Invoice/ticket download links can act as bearer credentials; store them privately and do not publish them. Do not infer tax treatment, settlement dates or accounting codes from an unrelated field. If the export lacks a required financial field, state the gap and obtain the appropriate organizer/provider record. Marking an invoice paid is a separate write operation; exporting records does not authorize changing payment state. A cancellation result does not prove a payment-provider refund has settled. ## Related financial workflows Use [invoice payments](https://developer.paydro.com/llm/accept-invoice-payments.md) for pay-later eligibility and recording a received transfer. Use [payouts and settlement](https://developer.paydro.com/llm/understand-payouts.md) to explain who holds the revenue and the status of an organizer payout. Reconcile platform fees, provider fees, customer surcharges and tax as separate components; do not apply historical support price estimates as current rules. Preserve decimal precision through exports and repeated edits. A correction to an issued invoice is not permission to overwrite its financial history. ## Verify Check sample invoices and credit documents against corresponding orders. Reconcile counts and totals per currency and status, including empty results and cancelled orders. Report coverage and any missing records instead of describing a partial export as complete. ## More documentation - [Exports](https://developer.paydro.com/en-us/docs/exports.md) - [Files and invoices](https://developer.paydro.com/en-us/docs/files-and-exports.md) - [Orders](https://developer.paydro.com/en-us/docs/orders.md) --- Source: https://developer.paydro.com/llm/find-shop-link.md # Find an existing Paydro shop link Use this path when the user has an account and wants to locate an existing shop for [website registration](https://developer.paydro.com/llm/sell-tickets.md). ## Find the event Ask the user to sign in to their usual Paydro organizer account and select the intended event. With authorized browser access, offer to navigate the account for them. Ask which event if it is ambiguous; do not pick a similarly named event silently. Open the event's Widgets page and copy its ordinary public shop link. The organizer route is `/{event_id}/widgets/index`; `event_id` is the event UUID, not the shop slug. Without browser access, tell the user: “Open your event in Paydro, go to Widgets, and paste the public shop link here.” Do not request their password. If no event exists, continue with [create a ticket shop](https://developer.paydro.com/llm/create-ticket-shop.md). If they cannot sign in or do not have an account, distinguish account recovery from [creating an account](https://developer.paydro.com/llm/create-paydro-account.md). ## Check and continue Open the public link when possible and check that it identifies the intended event. Report a closed, draft or inaccessible shop without changing its status merely to make the embed work. Do not substitute a reservation, invitation, preview or an in-progress checkout link. Once the public link is available, continue with [widget selection and code generation](https://developer.paydro.com/llm/use-shop-link.md). Do not stop after explaining where to find it if you already obtained it. --- Source: https://developer.paydro.com/llm/fix-integration.md # Fix and verify an integration Find a failure, correct the integration against the published contract and verify the affected workflow. Start with [summary](https://developer.paydro.com/llm/summary.md); collect the failing operation, sanitized response and expected outcome. ## Diagnose 1. Confirm the company/organizer origin; the developer host serves documentation, not account API requests. 2. Verify the method and exact documented path; do not infer generic `/api/v2` write routes. 3. Check event UUID versus shop slug, resource ownership and organizer permissions. 4. Check HTTPS Basic authentication server-side; invalid credentials can return legacy 403 JSON. 5. Send `Accept: application/json`; use `Content-Type: application/json` for JSON bodies. 6. Inspect status, content type, redirects and body together; HTTP 200 alone is not success. 7. Compare request envelopes and field formats with the OpenAPI operation and workflow guide. 8. For embeds, check the generated URL, visibility flags, iframe ID and resize-script initialization. ## Organization context and configuration failures Verify the selected organization and operation-specific rights; event visibility does not grant provider-management or file-management permission. Distinguish inaccessible controls caused by rights from navigation hidden on a small viewport before suggesting broader access. An invalid-grant or unavailable-payment-method error can require [provider recovery](https://developer.paydro.com/llm/configure-payment-providers.md), not a different order payload. Do not treat missing results as deleted data until checking filters, pagination and failed/stale requests. Organization membership removal and personal-account deletion are different workflows; do not promise one from the other. Confirm audit-log coverage for the particular change before claiming an action is traceable to an actor. ## Recovery Some writes succeed with redirects or unconventional JSON; read the resource before retrying. Honor `Retry-After` on authentication throttling and avoid retry loops with invalid credentials. Do not automatically replay a timed-out create, send, cancellation or payment-related operation. For synchronization gaps, check pagination, snapshot caps, deletion windows and the Sunday reset. Keep credentials, customer data and bearer document links out of logs and support reports. ## Verify the fix Use an authorized test event and synthetic records; `.test.test` hosts are local development, not a public sandbox. Test the original failure, a successful result and meaningful adjacent failure cases. Read resources back after writes; distinguish queue acceptance from delivery and cancellation from refunded money. Payment-provider tests require the organization's approved payment test setup. Report checks performed, evidence of success and remaining unverified side effects. ## More documentation - [Errors](https://developer.paydro.com/en-us/docs/errors.md) - [Retries](https://developer.paydro.com/en-us/docs/rate-limits-and-retries.md) - [Testing](https://developer.paydro.com/en-us/docs/testing.md) - [Going live](https://developer.paydro.com/en-us/docs/going-live.md) --- Source: https://developer.paydro.com/llm/guest-registrations.md # Manage guest registrations Arrange registration for speakers, sponsors or other invited guests. Start with [summary](https://developer.paydro.com/llm/summary.md); distinguish sending an invitation from creating an attendee record. ## Choose a supported workflow - Let guests register through a free ticket or an event promo code using the public shop. - Use organizer attendee import for an existing guest list; its preview and confirmation are required steps. - Use the organizer telesales workflow when staff need to complete a booking on a guest's behalf. There is no documented general-purpose stateless API for creating arbitrary orders or bulk attendees. ## Determine the allowance “Let these guests book” can mean a shared reusable offer, separate one-use codes or a limited ticket allocation. A shared code is transferable; a one-use code limits redemption, not necessarily the identity of the redeemer. | Control | Meaning to establish | | --- | --- | | Code-use limit | Number of qualifying orders/reservations using the code, not a headcount. | | Product maximum in ordinary mode | Maximum quantity of that product per order through the code. | | Ticket budget mode | Cumulative allocation per linked product across bookings through the code; do not assume a single shared pool across all products. | | Expiry | When the code stops being eligible; separate from the ticket's sale dates. | | Product stock and guarantees | Availability and any explicit guaranteed entitlement; a promo is not automatically a stock override. | For example, five code uses can allow more than five attendees when each order can contain multiple tickets. Use the organizer's explicit limit mode and the documented request fields; do not guess zero, blank or unlimited encodings. Save and re-read the settings, particularly after changing limit mode or removing an expiry. A hidden promo input does not disable an existing direct promo link. Use the actual generated link rather than inventing URL parameters. ## Invitation workflow 1. Select an event-owned product and the intended guest allowance. 2. POST `/{event_id}/promocodes/add/products.json` with `Promocode` and `ProductsPromocode` rows. 3. Configure the intended price, stock, per-product maximum and validity using the promo-code guide. 4. Require `ok:true` and retain the returned code ID; unused codes may not appear in the used-code map. 5. Read `/{event_id}/promocode_invites/view/{promocode_id}.json` for history and remaining allowance. 6. When sending invitations is requested, POST recipient rows to `promocode_invites/add/{promocode_id}.json` under the event. 7. Inspect `queued_indices` and `rejected`; retry only rejected recipients after correcting their details. ## Limits Invitation requests accept at most 100 recipients; company clearance and other limits apply. Queue acceptance does not prove delivery or completed registration. For waiting-list guests, use the waiting-list invitation workflow to preserve entry/code relationships. An import can send mail; review its delivery setting and validation preview before confirming. ## Waiting-list invitations An invitation is not a completed registration, and issuing another invitation can replace the previous code. Use current entry details to distinguish waiting, invited and registered outcomes; do not assume a freed place is automatically assigned. Invitation validity uses the documented hours, with an exact expiry timestamp; zero means no expiry. Do not reinterpret a 24-hour validity as the end of the next calendar day. For pay-later exceptions, follow [invoice payments](https://developer.paydro.com/llm/accept-invoice-payments.md); enabling a promo exception does not by itself establish invoice eligibility. ## Verify Use a synthetic recipient to verify the offer, allowed quantity and resulting registration. ## More documentation - [Promo codes and invitations](https://developer.paydro.com/en-us/docs/promo-codes.md) - [Import and checkout limits](https://developer.paydro.com/en-us/docs/api-coverage.md) - [Waiting lists](https://developer.paydro.com/en-us/docs/waiting-lists.md) --- Source: https://developer.paydro.com/llm/help-with-bookings.md # Help customers with bookings Find the correct booking, update supported details or resend a ticket. Start with [summary](https://developer.paydro.com/llm/summary.md); identify the event and booking or attendee without exposing customer records publicly. ## Workflow 1. Read the event's paginated orders or attendees using documented filters. 2. Match by stable IDs and verify the customer context; a name or email alone may match several records. 3. GET `/{event_id}/orders/detail_data/{order_id}.json` for current capabilities and delivery information. 4. For billing/contact changes, PUT `/{event_id}/orders/edit/{order_id}.json` with allowed `Order` fields. 5. For attendee changes, GET `/{event_id}/order_lines/edit_data/{attendee_id}.json`. 6. PUT `/{event_id}/order_lines/save/{attendee_id}.json` with allowed `OrderLine` fields and question UUID answers. 7. For a ticket change, read `order_lines/eligible_products.json`, then use the documented change-product action. 8. Re-read the changed record and report exactly what changed. ## Ticket type, price and recovery Changing the ticket product preserves the purchased price and tax snapshot; it is not an automatic charge or refund for the new catalog price. Establish both the desired entitlement and the financial difference before acting. For a downgrade needing money returned, use the supported [price-correction/refund workflow](https://developer.paydro.com/llm/cancellations-and-refunds.md), follow its completion state, then perform the eligible ticket-type change. For an upgrade needing additional payment, explain and use a supported checkout/payment workflow; do not claim the type-change action collects the difference. Verify the final ticket type, related questions, order relationship and financial records together. For missing tickets, distinguish an uncompleted booking from a paid booking with a delivery problem. Offer the current customer self-service entry or an authorized ticket resend, according to the customer's request. Self-service uses identity verification and access-window checks; do not promise that it is always available. The payer and attendee may differ. Do not expose all matching bookings based only on a supplied name or email. Question-level self-service editability is separate from access to the whole booking and from billing changes. ## Delivery and record identity An order edit can return `new_order_created`; follow that replacement UUID and refresh related records. An attendee UUID is not an order UUID; use the correct identifier for each action. POST `/{event_id}/order_lines/resend_one_ticket/{attendee_id}.json` only when a ticket resend is intended. Resending a ticket queues email; uncertain delivery is not a reason to repeatedly replay the request. Keep invoice and ticket download URLs private; they can authorize access without login. ## Verify Confirm the requested fields, current ticket and order relationship after saving. Keep payment changes and [cancellation/refunds](https://developer.paydro.com/llm/cancellations-and-refunds.md) in their own workflows. ## More documentation - [Orders](https://developer.paydro.com/en-us/docs/orders.md) - [Order management](https://developer.paydro.com/en-us/docs/order-management.md) - [Attendee management](https://developer.paydro.com/en-us/docs/attendee-management.md) --- Source: https://developer.paydro.com/llm/manage-entry.md # Manage entry at the event Check tickets and distinguish first admission, a repeat scan and an invalid ticket. Start with [summary](https://developer.paydro.com/llm/summary.md); select the correct event and authorized door-team access. ## Choose access Use the existing check-in UI for a ready-made scanner workflow. It supports an event-scoped access-code session through its exchange; raw access codes are not scan payloads. A custom integration uses organizer authentication on its server, never embedded credentials on scanner clients. ## Check-in API 1. POST `/{event_id}/acs/scan.json` with `Content-Type: application/json`. 2. Send `{"scan":"attendee_uuid"}` using the order-line UUID, not an order or product UUID. 3. Inspect the returned array for the matching ticket. 4. `scanned:false` with `checkedin:1` means this request recorded a first check-in. 5. `scanned:true` indicates a previous check-in; an empty array means no eligible matching ticket. 6. Present each result clearly to the operator; handle authentication and network failures separately. ## Corrections and reports Read attendee lists with `include=scan` for existing scan state. POST `/{event_id}/acs/delete.json` with `{"Acs":{"id":"scan_record_id"}}` for an intended correction. The removal ID is a scan-record ID, not the attendee UUID; re-read attendance after the legacy response. Use check-in and no-show exports when preparing attendance reports. Do not assume the API supplies offline synchronization or reuse retired scanner routes. ## Verify Test a first scan, repeat scan, wrong-event ticket, malformed UUID and access failure with synthetic tickets. Check current state after an uncertain request rather than labelling a network failure as an invalid ticket. ## More documentation - [Check-in](https://developer.paydro.com/en-us/docs/check-in.md) - [Attendees](https://developer.paydro.com/en-us/docs/attendees.md) - [Exports](https://developer.paydro.com/en-us/docs/exports.md) --- Source: https://developer.paydro.com/llm/manage-tickets.md # Manage ticket options Configure paid, free, donation or package tickets, pricing and availability. Start with [summary](https://developer.paydro.com/llm/summary.md); identify the event, ticket groups, prices, capacity and sales windows. ## Workflow 1. GET `/{event_id}/categories/index.json` and `/{event_id}/products/index.json`. 2. Create or select an event-owned category using the category guide. 3. GET `/{event_id}/products/add/free.json` for free-product defaults when relevant; this does not create a ticket. 4. PUT `/{event_id}/products/add/{type}.json` with the documented envelopes; retain the successful `id`. 5. Use `paid`, `free`, `donation` or `package` as appropriate; consult the product schema for required fields. 6. GET `/{event_id}/products/edit/{product_id}.json` before editing configuration. 7. PUT to that edit URL for supported pricing, dates, capacity and configuration changes. 8. Re-read products and verify their appearance and availability in the public shop. ## Important distinctions - `stock` is configured capacity; `current_stock` accounts for sales, reservations and pending holds. - Shared pools, packages, visibility and sales windows can further restrict availability. - Reading stock does not reserve a ticket; checkout makes the final availability decision. - Use the documented decimal money formats and event currency. - Deletion can be prevented by existing use; do not replace a sold product merely to change its label. ## Diagnose unavailable tickets Check in order: event publication, ticket sale dates, visibility, per-order limits, current stock, shared pools/package constraints and the applied promo. A valid promo with no eligible available product can still yield an empty offer. Distinguish “sold out and shown” from “hidden when sold out”; neither changes the underlying count of purchased tickets. For a private early-bird exception, inspect both the hidden offer and its sale period rather than extending public availability unintentionally. ## Reservations, cancellation and waiting lists A stock read is a snapshot; reservations and pending operations can change availability before checkout completes. Cancellation or reservation release can free capacity. If the organizer wants waiting-list allocation instead of public resale, establish the intended stock/visibility policy before changing it. Use the [waiting-list invitation workflow](https://developer.paydro.com/llm/guest-registrations.md) explicitly; do not infer that joining the list reserves a ticket or guarantees automatic admission. For packages, inspect component and shared-pool constraints as well as the package's own stock. When correcting counts, preserve sale periods and visibility; a repair must not silently reopen an expired early-bird offer. ## Verify Check an early-bird transition, exhausted capacity and package/shared-pool constraints when configured. Test creation only with synthetic data; re-read before retrying uncertain writes. ## More documentation - [Product management](https://developer.paydro.com/en-us/docs/product-management.md) - [Availability](https://developer.paydro.com/en-us/docs/product-availability.md) - [Categories](https://developer.paydro.com/en-us/docs/categories.md) --- Source: https://developer.paydro.com/llm/sell-tickets.md # Sell tickets on my website Use this as a conversation workflow, not a request to summarize Paydro documentation. Follow the user's requested scope: “do not change code” means provide the finished snippet in chat without editing files; an explicit plan-only request means a plan only. Implement when requested. ## Start with the missing information 1. Read the conversation for a public shop link and prior choices; do not ask for information already supplied. 2. If the link is missing, ask: “What is your public Paydro shop link? If you do not have one, do you already have a Paydro account or need to create one?” Wait for the answer before generating integration code. 3. With a link, follow [use an existing shop link](https://developer.paydro.com/llm/use-shop-link.md): ask which widget, then the embed's Image, Info panel, Title, Date and Location choices, then whether to add it directly to a page or output copyable code. Reuse answers already supplied; Date is conditional on the shop showing dates. 4. With an account but no link, ask: “Do you want to find an existing shop in Paydro, or have me help create a new shop?” Follow [find a shop link](https://developer.paydro.com/llm/find-shop-link.md) or [create a ticket shop](https://developer.paydro.com/llm/create-ticket-shop.md). 5. Without an account, follow [create a Paydro account](https://developer.paydro.com/llm/create-paydro-account.md), then create the shop and return to widget selection. Ask at most two short questions at a time. Present the next relevant choice, not a long implementation plan followed by missing prerequisites. ## Inspect the destination project Inspect the user's actual website, target page, framework, button styles and responsive layout while waiting for answers. Documentation hosted by Paydro is not evidence that the destination uses CakePHP, Vue or Tailwind. Do not copy Paydro's marketing design unless that is the destination project. If the destination page is unclear, ask where tickets should appear. If project access is unavailable, request its framework and an existing component or design reference, and identify any styling assumptions. ## Deliver code, then verify within scope Once the link, widget, applicable display choices and delivery mode are known (and the target page for direct insertion), give a short concrete plan and produce the complete integration with actual URLs and the site's existing styles. Do not send users to the widget generator for a routine link that this guide can handle. For code changes, use the project's conventions and run its relevant checks. For “do not change code”, show the exact snippet/component and insertion point in chat; label browser verification as pending unless a preview was actually tested. Keep a normal shop link visible alongside an embed. Match surrounding layout and button styles; use [branding settings](https://developer.paydro.com/llm/branding-and-language.md) for the checkout itself. ## Desktop and mobile verification - Open the actual target page at desktop (1280px and 1440px) and mobile (375px and 390px), including client-side navigation if applicable. - Check button appearance, keyboard focus, touch controls, wrapping, overflow and the ordinary shop link. - For an embed, check script loading, iframe resizing, hidden sections, scrolling and fields while the mobile keyboard is open. - Use an authorized test event and payment sandbox for ticket selection, validation, payment handoff, confirmation and return-state checks. Do not place real paid orders just to test a layout. - Report tested URLs, viewport sizes, screenshots where available, actual results and anything untested. Viewport emulation alone is not verification on mobile Safari or a physical device. Do not claim checkout success from an iframe message or return URL alone. ## More documentation - [Embed guide](https://developer.paydro.com/en-us/docs/embed-ticket-shop.md) - [Testing](https://developer.paydro.com/en-us/docs/testing.md) --- Source: https://developer.paydro.com/llm/set-up-event.md # Set up an event Create or copy an event, then configure and review it before opening sales. Start with [summary](https://developer.paydro.com/llm/summary.md); obtain the company, name, dates, timezone and currency. ## Workflow 1. Check organizer permissions and the correct company hostname. 2. POST `/events/add.json` with the documented `Event` fields. 3. Require `ok:true` and retain the returned `event_id`; read the event back. 4. Alternatively POST `/events/duplicate/{event_id}.json` for an authorized existing event; retain the returned `id`. 5. Configure [ticket options](https://developer.paydro.com/llm/manage-tickets.md) and [registration questions](https://developer.paydro.com/llm/collect-attendee-information.md). 6. PUT `/{event_id}/events/edit.json` for allowed changes; send both dates when changing dates. 7. Review public information, ticket availability, sender details and checkout in the organizer UI. 8. When opening sales is within the request, PUT `/{event_id}/events/status/open.json` and verify the shop. ## Limits Creation and publication are separate operations. Opening can require company clearance. Transitioning a concept/test event can clean concept test state; review before publishing. Use `close` or `sold_out` only for the intended shop status change. Protected settings are filtered; a successful response does not prove every submitted field changed. Do not retry a timed-out creation until checking whether an event was already created. ## Duplication and lifecycle consequences After duplication, review the destination organization, payment setup, invoice details, sale dates, copied questions and integrations. Do not assume source payment credentials or external mailing connections carry over; validate the destination's configuration before publication. Use [provider setup](https://developer.paydro.com/llm/configure-payment-providers.md) for readiness checks and the actual collection route. Closing sales, marking the shop sold out and financial settlement are different states; follow [payout guidance](https://developer.paydro.com/llm/understand-payouts.md) for the financial outcome. A future ticket sale date can hide tickets even during preview. Inspect it without changing the event date just to make a test succeed. Opening a concept event can remove its test registrations; review that consequence before publishing and do not use real payments to test it. Date changes can affect reporting and financial documents. Do not move the event date as an undocumented workaround for payment or settlement restrictions. Do not assume an event with existing orders can be deleted; preserve its order and financial relationships. ## Verify Read the resulting ID, name, dates, timezone and currency; verify ticket configuration and shop status separately. ## More documentation - [Events and writable fields](https://developer.paydro.com/en-us/docs/events.md) - [Event/catalog recipe](https://developer.paydro.com/en-us/docs/integration-recipes.md) - [Writing data](https://developer.paydro.com/en-us/docs/writing-data.md) --- Source: https://developer.paydro.com/llm/show-events.md # Show our events Build a public event listing using a server-side integration and public shop links. Start with [summary](https://developer.paydro.com/llm/summary.md); decide which organization's events and dates should be published. ## Workflow 1. Authenticate on the organizer/company origin and GET `/events/my.json`. 2. Read the `events` array; each record contains an `Event` object. 3. Pass a four-digit `year` when requesting a particular year or historical events. 4. GET `/api/v2/events/{event_id}` for the selected event details. 5. Select public fields such as name, dates, timezone and `direct_link` for your website's response. 6. Verify published status and the actual shop link before displaying a registration button. 7. Refresh changed dates and links; use UUIDs to update existing records. ## Limits - Discovery defaults to this and the previous year; without `year` it has a 2,000-event cap. - Names containing “test” are excluded; a known test UUID can still be accessible directly. - `/api/v2/events` is not the documented event-list endpoint. - Organizer responses can contain internal metadata: do not forward entire responses to visitors. - Interpret event dates in their configured timezone; do not infer an offset from SQL timestamps. ## Verify Compare the listing with the selected published events, including an empty year and a changed date. Check that each link opens the intended public shop and that credentials never reach the browser. ## More documentation - [Events](https://developer.paydro.com/en-us/docs/events.md) - [Data types](https://developer.paydro.com/en-us/docs/data-types.md) - [Website registration](https://developer.paydro.com/llm/sell-tickets.md) --- Source: https://developer.paydro.com/llm/understand-payouts.md # Understand payouts and settlement Explain where event revenue is held, what remains to be done and which evidence establishes completion. Start with [summary](https://developer.paydro.com/llm/summary.md); identify the organization, event and the payment route actually used. ## Determine the intended outcome Distinguish a customer payment, an organizer-provider payout, a Paydro settlement and a settlement document. Ask whether the organizer needs a status explanation, a missing document or a payout request. A request to inspect revenue does not itself authorize changing bank details or initiating financial actions. ## Workflow 1. Inspect the event's payment configuration and the relevant transaction records. Do not infer historical routing solely from the organization's current default provider. 2. For payments collected through the organizer's own provider account, inspect that provider's payout records through authorized tools or ask the organizer to check them. 3. For platform-managed collection, inspect the event dashboard's payout information, request eligibility and settlement documents. 4. Check the event end date, organization verification, required bank details, existing requests and previous settlements when explaining a blocked or unavailable request. 5. If requesting a payout is within scope, use the organizer's available payout workflow and inspect its resulting status. Do not invent a payout API or repeat an uncertain request. 6. Report separately what was collected, requested, documented and confirmed transferred. State which stage remains unverified. ## Consequences and common misunderstandings - Closing ticket sales does not mean the event has been financially settled or that money has been transferred. - A payout request is a request for processing, not a bank transfer. An available settlement invoice is not independent proof of receipt. - A customer invoice, a credit invoice and a settlement invoice describe different events; do not substitute one for another. - Provider configuration changes where collection happens; it is not simply a switch between earlier and later payout dates. - Do not change an event date or provider configuration just to make a payout control available. Those settings have wider operational and financial consequences. - Use the current eligibility information. Do not promise historical support estimates as a payout deadline or calculate a payable balance from ticket revenue alone. ## Verify Compare the same event, currency and collection route across the dashboard, financial documents and available provider records. Distinguish deductions, previous payouts and refunds; escalate unexplained differences without claiming they are resolved. Keep bank details, payment references and documents private. ## Related guidance - [Configure payment providers](https://developer.paydro.com/llm/configure-payment-providers.md) - [Prepare financial records](https://developer.paydro.com/llm/financial-records.md) - [Handle refunds](https://developer.paydro.com/llm/cancellations-and-refunds.md) - [Workflow limits](https://developer.paydro.com/en-us/docs/api-coverage.md) --- Source: https://developer.paydro.com/llm/use-shop-link.md # Use an existing Paydro shop link Continue [website registration](https://developer.paydro.com/llm/sell-tickets.md) once the user has supplied a public shop link. ## Ask which widget Ask: “Would you like a Buy tickets button that opens Paydro, the ticket shop embedded in your page, or both?” Skip this question if already answered. For an embed or both, ask: “Which parts should the embedded shop show? Please choose Show or Hide for each: Image, Info panel, Title, Date, Location.” Present these as one checklist, matching the organizer widget options; suggest choices from the destination page but wait for the user's selections before generating code. Offer Date only when the event shows dates on its shop. If that setting is unknown, ask for the Date preference conditionally and explain that it applies only when dates are enabled. Skip these display questions for a button-only integration and reuse any selections already supplied. After the display choices, ask: “Should I add the widget directly to a page in this project, or give you the widget code here to copy?” Reuse an explicit prior instruction (including “do not change code”) instead of asking again. Wait for this choice before editing files; for direct insertion, ask which page if it is not already clear. Inspect the supplied URL and, when accessible, its public destination. Use the actual HTTPS origin and event slug; do not assume every organization uses the same hostname. A standard shop link is `https://ORIGIN/EVENT-SLUG`. Event UUIDs are not public slugs. Do not construct an organizer widget URL from a slug. If the link is a preview, invitation, reservation, checkout-state URL, contains unexplained parameters, or has a nonstandard path, obtain the ordinary public link or generated widget before deriving an embed. Do not silently discard meaningful parameters. Do not invent a hostname, slug, event UUID or theme parameter. If inaccessible, explain what could not be verified and request generated code only when needed to resolve the URL format. ## Generate the selected integration Inspect the destination site's existing button/component and layout. Produce code in that framework, with its existing classes and actual URLs; the examples below are templates, not finished user output. Escape URLs and labels for the output language (including `&` in HTML attributes). Public embeds need no organizer API credentials. ### Button Use the actual public link with the site's existing anchor/button styles. A navigation link is sufficient; no SDK is needed. If using Paydro's standalone button styling instead, include its stylesheet once: ```html Buy tickets ``` Preserve the stylesheet version query when copying generated code. The button opens the shop; it is not a modal widget. ### Embedded shop For a verified standard public link, append `/embed?embed=true` to the origin and slug path, with no doubled trailing slash. The switches are `image`, `info`, `title`, `date` and `location`: append `=false` to hide a section; omit enabled switches. Date applies only when the shop shows dates. ```html Open ticket shop ``` Replace both hostnames, both shop paths and `data-shop` using the supplied link. Include only the switches the user chose. Keep the iframe ID and slug: the script uses them for resizing and cookie-based checkout-state restoration. Include one shop iframe per page. Load the script once after the iframe and before DOMContentLoaded. It is not an automatic SPA mount integration: inspect the actual lifecycle and verify initialization on direct loads and client navigation. Do not assume a late script insertion initializes it. If the framework cannot support that lifecycle reliably, explain the limitation and agree on a working integration; do not present a broken snippet as ready to use. The generator caps width at 650px; use the destination's existing responsive layout utilities as appropriate. Website CSS cannot style a cross-origin iframe's contents; use Paydro shop-design settings for those. If omitting the resize script, enable scrolling and size the iframe appropriately; verify the full form is reachable. ## Finish For direct insertion, add the selected widget to the agreed page using its existing design and follow the desktop/mobile checks in [website registration](https://developer.paydro.com/llm/sell-tickets.md). For code output, return the complete copyable widget with real values and placement instructions in chat without editing files; distinguish suggested checks from tests actually run. For nonstandard links, the organizer's `/{event_id}/widgets/index` generator provides authoritative code; obtain the event UUID through authorized organizer access, not from the public slug. --- Source: https://developer.paydro.com/en-us/docs/getting-started.md --- description: "Build your first integration with a ticket shop or a read request to the Paydro API." group: "Get started" order: 1 --- # Getting started Build your first integration with a ticket shop or a read request to the Paydro API. This guide is for developers connecting a website or server application to Paydro. For the API path, you should know how to run a terminal command and read JSON. By the end, you will have retrieved an event and checked that it is the one your integration needs. ## Choose your starting point {#choose-your-starting-point} - [Embed registration and checkout](https://developer.paydro.com/en-us/docs/embed-ticket-shop.md): you need your public shop URL and access to your website’s HTML. No API credentials are needed; continue with the embed guide. - **Build a server integration**: follow the steps below, then [synchronize orders and attendees](https://developer.paydro.com/en-us/docs/synchronizing-data.md) or use the [integration recipes](https://developer.paydro.com/en-us/docs/integration-recipes.md). - **Connect an existing service**: follow the [HubSpot](https://developer.paydro.com/en-us/docs/hubspot.md) or [Mailchimp](https://developer.paydro.com/en-us/docs/mailchimp.md) setup guide. ## Prepare your access {#prepare-your-access} 1. Ask your organization administrator for an active Paydro organizer account with access to the relevant event. Use a dedicated account for a server integration where your organization supports one. 2. Set your API origin to your organization’s Paydro host, or `https://shop.paydro.com`. The developer hostname serves documentation. 3. Copy the event UUID from the organizer event URL. Event slugs in public shop URLs are different from UUIDs. 4. Store the account email and password in your server’s secret environment. Keep them out of browser JavaScript. Use an [authorized test event](https://developer.paydro.com/en-us/docs/testing.md#prepare-test-data). The local `.test.test` sites are for an installed development environment; they are not a public sandbox. This first request only reads event data. ## Make your first request {#make-your-first-request} In Bash or Zsh, replace the email and example UUID below with your organizer email and event UUID. Set the origin without a trailing slash. Enter your password at the hidden prompt; it will not be saved in shell history. ```bash export PAYDRO_ORIGIN="https://shop.paydro.com" export PAYDRO_EMAIL="integration@example.com" export EVENT_ID="11111111-1111-4111-8111-111111111111" printf 'Paydro password: ' read -rs PAYDRO_PASSWORD printf '\n' export PAYDRO_PASSWORD ``` Choose one client below and run it from that same terminal. Use cURL directly; save PHP as `first-request.php` (including the opening ` getenv('PAYDRO_EMAIL') . ':' . getenv('PAYDRO_PASSWORD'), CURLOPT_HTTPHEADER => ['Accept: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, ]); $response = curl_exec($ch); if ($response === false) throw new RuntimeException(curl_error($ch)); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); unset($ch); if ($status !== 200) throw new RuntimeException('HTTP ' . $status); $data = json_decode($response, true, 512, JSON_THROW_ON_ERROR); if (($data['Event']['id'] ?? null) !== getenv('EVENT_ID')) { throw new RuntimeException('Expected the requested Event'); } echo json_encode($data, JSON_PRETTY_PRINT), PHP_EOL; ``` ```node group=first-request const { PAYDRO_ORIGIN, PAYDRO_EMAIL, PAYDRO_PASSWORD, EVENT_ID } = process.env; const credentials = Buffer.from(`${PAYDRO_EMAIL}:${PAYDRO_PASSWORD}`).toString('base64'); const response = await fetch(`${PAYDRO_ORIGIN}/api/v2/events/${EVENT_ID}`, { headers: { Authorization: `Basic ${credentials}`, Accept: 'application/json' }, redirect: 'error', signal: AbortSignal.timeout(30000), }); if (response.status !== 200) throw new Error(`HTTP ${response.status}`); const data = await response.json(); if (data.Event?.id !== EVENT_ID) throw new Error('Expected the requested Event'); console.log(JSON.stringify(data, null, 2)); ``` ```python group=first-request import json, os, requests response = requests.get( os.environ['PAYDRO_ORIGIN'] + '/api/v2/events/' + os.environ['EVENT_ID'], auth=(os.environ['PAYDRO_EMAIL'], os.environ['PAYDRO_PASSWORD']), headers={'Accept': 'application/json'}, timeout=30, allow_redirects=False, ) if response.status_code != 200: raise RuntimeError(f'HTTP {response.status_code}') data = response.json() if data.get('Event', {}).get('id') != os.environ['EVENT_ID']: raise RuntimeError('Expected the requested Event') print(json.dumps(data, indent=2)) ``` ## Read the result {#read-the-result} A successful v2 event request returns an object with an `Event` property. The object below is a shortened illustrative response; actual events contain additional settings. ```json {"Event":{"id":"11111111-1111-4111-8111-111111111111","name":"Community Summit","currency":"EUR","start_date":"2026-11-20 09:00:00"}} ``` Expect HTTP `200`, a JSON body, and `Event.id` equal to `EVENT_ID`. cURL prints the response headers and body; the other examples check the status and event ID before printing JSON. Confirm the event name, too. A successful HTTP status alone does not prove that a legacy API operation succeeded. When finished, run `unset PAYDRO_PASSWORD`. For unattended requests, supply credentials through your server’s secret manager. ## Troubleshoot your first request {#troubleshoot-your-first-request} | Result | Next step | | --- | --- | | `403` with `Unauthorized` | Check the email, password and active account status. Stop repeated attempts; see [authentication failures](https://developer.paydro.com/en-us/docs/authentication.md#failed-authentication). | | Redirect, login HTML or JSON parsing error | Check the API origin and that credentials were exported in the same terminal. Do not follow login redirects as API responses. | | `404` or `invalid_id` | Use the organizer host, the exact request path and an event UUID you can access. A public shop slug cannot replace the UUID. | | `429`, `503` or timeout | Follow [retry guidance](https://developer.paydro.com/en-us/docs/rate-limits-and-retries.md); honor `Retry-After` when present. | See [handling errors](https://developer.paydro.com/en-us/docs/errors.md) for other responses and what to include in a support request. ## Continue building {#continue-building} - Understand origins, paths and response envelopes in [API basics](https://developer.paydro.com/en-us/docs/api-basics.md). - Look up methods, parameters and response schemas in the [API reference](https://developer.paydro.com/en-us/reference/overview), or download [OpenAPI JSON](https://developer.paydro.com/openapi/v2.json). - Before writing data, check the [permissions matrix](https://developer.paydro.com/en-us/docs/permissions.md#operation-matrix) and [workflow limits](https://developer.paydro.com/en-us/docs/api-coverage.md). - Complete [integration testing](https://developer.paydro.com/en-us/docs/testing.md) and the [go-live checklist](https://developer.paydro.com/en-us/docs/going-live.md) before enabling production automation. --- Source: https://developer.paydro.com/en-us/docs/authentication.md --- description: "Authenticate server requests with Paydro organizer credentials over HTTPS." group: "Get started" order: 2 --- # Authentication Authenticate server requests with Paydro organizer credentials over HTTPS. Organizer API requests use HTTP Basic authentication with an active Paydro organizer account. The username is the account email address and the password is the account password. Requests retain the user’s company and event rights. The reference marks exceptions: [public stage reads](https://developer.paydro.com/en-us/docs/stages.md) and [bearer download links](https://developer.paydro.com/en-us/docs/files-and-exports.md) do not require Basic credentials. Treat bearer links as secrets: anyone with an eligible link can use it. ## Send credentials {#send-credentials} Send `Authorization: Basic …` over HTTPS. Your HTTP client encodes `email:password` in Base64; this encoding is not encryption. Use the client’s Basic authentication option instead of building a URL containing a password. ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/api/v2/events/$EVENT_ID" ``` The reference declares an OpenAPI HTTP Basic security scheme. Public documentation and the specification download do not require authentication. Paydro API credentials belong on the service host, not this developer site. ## Account access {#account-access} The account must be active, not deleted, and authorized for the organization and event. A normal organizer browser session is separate from a server request with Basic authentication. Verify your integration credentials directly with an authorized read request. ## Failed authentication {#failed-authentication} Incorrect Basic credentials return a legacy `403` response containing `status`, `title`, and `detail`. Repeated failed attempts may be rate limited. Missing authentication can produce a login redirect or a legacy JSON error; treat either as an authentication failure, even if the final response is `200`. ## Store secrets safely {#store-secrets-safely} Keep credentials in your server environment or secret manager and exclude Authorization headers from logs. Coordinate account password changes with every integration using that account: update its stored secret and verify an authorized read request after the change. This API does not provide a self service API key or Paydro OAuth token flow through this portal. --- Source: https://developer.paydro.com/en-us/docs/api-basics.md --- description: "Understand service origins, v2 routes, JSON resources, and response conventions." group: "Get started" order: 3 --- # API basics Understand service origins, v2 routes, JSON resources, and response conventions. Paydro exposes an existing v2 event endpoint and authenticated JSON resources used for organizer data. Their paths and response envelopes differ. The OpenAPI document describes them together while preserving their existing formats. ## Choose an API origin {#choose-an-api-origin} Use your organization’s Paydro hostname or `https://shop.paydro.com`. For local development, use the organizer hostname configured in your development environment. Set `PAYDRO_ORIGIN` without a trailing slash so paths can be appended consistently. The documentation and [OpenAPI contract](https://developer.paydro.com/openapi/v2.json) are available on this site's current hostname. Send API requests to your configured organizer origin. Dedicated developer hosts serve documentation and return a documentation 404 for organizer requests. ## Paths and methods {#paths-and-methods} The event detail path is `/api/v2/events/{event_id}`. Other resources use event UUIDs at the start of the path and a `.json` suffix, such as `/{event_id}/products/index.json`. Use the method in the reference and `Accept: application/json`. Use the single documented write method (PUT when supported, otherwise POST) with `Content-Type: application/json`; uploads use multipart and exports return files. The presence of generic v2 routing does not establish another working endpoint. In particular, use `/{event_id}/products/add/{type}.json` to create products; do not infer a v2 product route. ## Response envelopes {#response-envelopes} - Event detail: `{"Event": {...}}`. - Ticket products: a JSON array of product objects. - Order lists: an array of records with an `Order` property. - Attendee lists: an array of records with an `OrderLine` property. - Bulk resources: event keyed maps with compact field names. Always read the operation schema before parsing a response. Preserve identifiers as strings and allow additional fields to appear. ## Compatibility {#compatibility} The reference covers existing reads, organizer writes and file responses. Its document version does not add new server endpoints. Read [writing data](https://developer.paydro.com/en-us/docs/writing-data.md) for request envelopes, success fields and retries. HTML/session-dependent workflows, internal callbacks and retired scanner routes remain outside the standard JSON contract. ## Choose a workflow {#choose-a-workflow} Read [API coverage and workflow limits](https://developer.paydro.com/en-us/docs/api-coverage.md) before automating company promo codes, CSV imports, refunds or checkout. [Integration recipes](https://developer.paydro.com/en-us/docs/integration-recipes.md) connect the supported resources, and [stage state](https://developer.paydro.com/en-us/docs/stages.md) documents the public display/SSE exception. --- Source: https://developer.paydro.com/en-us/docs/permissions.md --- description: "Understand organizer, company, and event access for integrations." group: "Get started" order: 4 --- # Permissions Understand organizer, company, and event access for integrations. Organizer API access follows the account’s existing Paydro rights. Authentication establishes the account; authorization determines which company/event data it can read and change. File and customer document bearer downloads are described separately in [Files](https://developer.paydro.com/en-us/docs/files-and-exports.md). ## Organization membership {#organization-membership} Ask your organization administrator to give the integration account the appropriate organizer role. Use the correct company hostname when working with a specific organization. A UUID identifies a record; possession of the identifier does not grant access to it. ## Event access {#event-access} Event scoped requests check the event against the current account. List resources may use the account’s accessible companies, while event discovery applies a live company membership check. As a result, an event list and a bulk response may have different scopes. Use explicit event scoped reads when you need a single event. ## Account lifecycle {#account-lifecycle} Inactive or deleted accounts cannot authenticate. Company membership and event roles can change after an integration is deployed. When requests start failing, check the account and its rights before retrying repeatedly. ## Operation permissions {#operation-matrix} Company membership types are 0 (sales), 1 (manager) and 2 (administrator). Event access generally checks active company membership rather than a distinct API scope. Additional checks below are enforced by the operation; an organizer button's visibility does not create an API permission boundary. | Operations | Required access | Additional restrictions | | --- | --- | --- | | Event, product, category/question, order, attendee, waiting-list, promo-code and traffic reads; event exports | Active organizer with access to the event's company. | Individual ownership, filters and resource availability still apply. Discovery and bulk reads can have narrower company/date scopes. | | Event creation, editing, duplication and shop-status changes | Company manager or administrator (type ≥ 1). | Use the requested company host; dates, sales state and company clearance can block a change. | | Product, category and question writes | Active organizer with event access. | Same-event categories/package members, provider configuration, used products, protected categories and question eligibility are checked. These controllers do not add an editor-type requirement to every published write. | | Order and attendee edits/actions | Active organizer with event access. | Current payment/lifecycle capabilities decide whether editing, cancellation or a reservation action is allowed; archived paid options remain protected. | | Waiting-list invitations/settings/removal; event promo-code writes/invitations | Active organizer with event access. | Entry/product/code ownership, invitation limits and referenced-code rules apply. | | Add organizer notes | Active organizer with rights to the note's parent event. | Parent must be Event, Order or OrderLine; text is 2–500 characters after trimming. | | Edit organizer notes | The note's author, still authorized for its event. | Only within 15 minutes of creation; text is the writable field. | | Bulk event-note reads; organizer/company directories | Active organizer; membership-scoped records. | Bulk notes include Event parents only. An administrator override on one event read does not imply an unbounded company directory. | | Check-in and scan removal | Authorized organizer; scanning also accepts an established scoped check-in session. | A raw access code is not a Basic credential. Use the existing check-in exchange; ticket/event ownership is checked. | | Event attachment upload/removal | Company administrator (type 2). | Existing file size/type/storage and attachment ownership rules apply. Multipart upload uses POST. | | Stage state writes | Company manager or administrator (type ≥ 1). | Stage ID and event ID must match; a new default stage uses the event UUID. | | Stage state reads/SSE; generated bearer document downloads | Public stage URL or possession of the document's bearer URL. | These explicit exceptions do not require organizer Basic. Treat bearer documents as private links; stage state must contain public display data. | Platform administrator overrides exist in common authorization, but several actions also perform their own membership/capability checks. Use a normal company account with the required rights to verify your integration. See [API coverage](https://developer.paydro.com/en-us/docs/api-coverage.md) for company promo forms, imports and refunds that remain organizer workflows. ## Handle access failures {#handle-access-failures} Expect a permission error or legacy JSON error for inaccessible or missing events. Check the status, content type, and body. Do not follow a redirect and treat the resulting login page as event data. There are no documented API token scopes in this integration surface. Grant the account the minimum organizer rights that your workflow needs, and verify both an authorized request and an inaccessible event in your test environment. --- Source: https://developer.paydro.com/en-us/docs/testing.md --- description: "Verify requests, parsing, and recovery using an authorized test event." group: "Get started" order: 5 --- # Testing your integration Verify requests, parsing, and recovery using an authorized test event. Test against an organization and event you are authorized to use. A local `.test.test` hostname is a development environment, not a publicly available Paydro sandbox. ## Prepare test data {#prepare-test-data} Create or obtain a test event through your organization’s normal workflow. Use synthetic attendee names and addresses, a small product list, and example orders. Record the event UUID separately from its public shop slug. ## Verify read requests {#verify-read-requests} 1. Retrieve the event and confirm its identifier. 2. Retrieve ticket products and check their IDs and price representations. 3. Retrieve order and attendee lists and verify relationships by ID. 4. Try an empty result and a subsequent page. 5. Check incorrect credentials and an inaccessible identifier. ## Verify writes {#verify-writes} Test product creation/editing, a validation failure, a foreign identifier and the returned success fields using synthetic records. Re-read each resource afterwards. Use isolated waiting-list and attendee records for invitation/answer tests; explicitly account for queued mail and replacement codes. Payment/provider actions require your approved payment test setup. The published request/response examples are synthetic and schema-validated. Documentation discovery also probed local read shapes and deliberately rejected product, invitation, attendee and scan writes before saving. Successful note creation/editing and category editing are additionally exercised through controllers with real models and synthetic records in an isolated test database; the note boolean serializer and persisted values are checked. These tests replace account access and cache invalidation dependencies and do not represent a complete HTTP authentication test. Other successful writes, binary downloads, continuous stage streaming and email/provider delivery remain source-reviewed. This verification boundary is recorded in the OpenAPI descriptions. ## Verification coverage {#verification-matrix} | Check | What it demonstrates | What still needs integration verification | | --- | --- | --- | | OpenAPI validation and synthetic examples | Standard structure, field constraints, conditional question options and four language samples. | Schema validity does not prove a server save or side effect. | | Local fixture HTTP reads and rejected writes | Selected serializers, authentication, resource shapes and rejection boundaries. | Successful mutation paths and all role combinations. | | Isolated successful note/category writes | Real model persistence, note JSON boolean results, parent/author assignment and cross-event category rejection. | End-to-end authorization, shared cache invalidation and the remaining write operations. | | Stage authorization tests | Editor access and rejection of foreign state/unsupported write methods. | State replacement over HTTP, SSE reconnection and concurrent writers. | | Invitations, uploads/downloads and payments | Documented controller/model behavior and synthetic request formats. | Mail receipt, uploaded/downloaded file bytes and sandbox payment-provider outcomes. | For a successful write test, record the resource before the request, assert the documented success field, re-read persisted fields, and verify that another event cannot change it. Use dedicated mail addresses and provider test credentials when exercising external effects. The [recipes](https://developer.paydro.com/en-us/docs/integration-recipes.md) provide complete catalog and invitation/answer sequences. ## Recover synchronization {#recover-synchronization} Run a full synchronization, interrupt it, and repeat it. Upserting by ID should produce the same local result without duplicated records. Test a changed record, a cancelled order, a deletion notification, and a resynchronization after the weekly delta window has changed. ## Embedding and checkout {#embedding-and-checkout} Read API tests do not verify a payment flow. When embedding, test registration, validation, responsive behavior, and the checkout handoff using the organization’s approved payment test configuration. Keep live payment credentials out of test flows. ## Move to production {#move-to-production} Replace the origin and identifiers deliberately; keep credentials in your secret manager. Review the [go live checklist](https://developer.paydro.com/en-us/docs/going-live.md) and confirm the first production read before enabling scheduled imports. --- Source: https://developer.paydro.com/en-us/docs/data-types.md --- description: "Interpret identifiers, dates, money, flags, and optional legacy fields." group: "API fundamentals" order: 6 --- # Data types Interpret identifiers, dates, money, flags, and optional legacy fields. Response fields reflect the existing application and database serializers. Some values that look numeric remain strings; other responses convert them to numbers. Parse the schema for each operation and avoid relying on one serializer’s behavior across all endpoints. ## Identifiers {#identifiers} Event, order, attendee, and product IDs are UUID strings. Public shop slugs are human readable identifiers for URLs and are not substitutes for event UUIDs. Preserve IDs exactly when using them as map keys. ## Dates and timezones {#dates-and-timezones} Event dates and ordinary record timestamps commonly use `YYYY-MM-DD HH:MM:SS` without an offset. Interpret them using the event or organization’s applicable timezone. Do not append `Z` and silently turn local event time into UTC. Compact order snapshots use Unix seconds in `d`. Compact attendees use a text creation date in `d` and Unix seconds for the order creation time in `od`. `pendingActionInitiatedAt` uses an ISO 8601 timestamp or null. ## Money and currencies {#money-and-currencies} Product `price` can be a decimal string. Compact monetary fields such as `t` are decimal amounts in the event currency, not integer cents. Use decimal arithmetic and keep the currency alongside the amount. Consult the event’s VAT settings before presenting tax inclusive totals. ## Flags and missing values {#flags-and-missing-values} Legacy flags can be integers or numeric strings. Derived payment fields can be booleans. Optional compact fields may be omitted when empty; a missing `p` must not be confused with a guaranteed settled payment. Empty maps may serialize as `[]`. Handle missing, null, and empty values separately. --- Source: https://developer.paydro.com/en-us/docs/writing-data.md --- description: "Send authenticated organizer writes, validate legacy results, and handle retries and side effects." group: "API fundamentals" order: 7 --- # Writing data Create and manage event data with the existing organizer HTTP resources. Use the methods and paths in the [OpenAPI reference](https://developer.paydro.com/en-us/reference/overview). The reference publishes PUT when supported, and POST for actions that require it. These action URLs retain CakePHP model envelopes and existing lifecycle rules. They are not generic REST updates or JSON Patch endpoints. ## Authenticate and authorize {#authenticate-and-authorize} Send HTTP Basic over HTTPS from your server, using an active organizer account on your configured organization origin. Basic requests use the organizer's company and event permissions. Browser sessions retain their CSRF requirements. Event UUIDs and nested product, category, attendee and promo IDs must be authorized for the requested event. File management requires company administrator rights. Event opening can require company clearance. Orders and attendees also enforce payment-state capabilities. Review [permissions](https://developer.paydro.com/en-us/docs/permissions.md) before choosing an integration account. ## Send JSON envelopes {#send-json-envelopes} Send `Accept: application/json` and `Content-Type: application/json`. Use the action's envelope, such as `Product`, `OrderLine`, `Waitinglist` or `Comment`. Uploads instead use multipart form data. Set `PAYDRO_ORIGIN` to your organizer origin; dedicated developer hosts serve documentation. ```curl-·-creates-a-free-ticket curl --fail-with-body --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --request PUT \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data '{"Product":{"title":"General admission","price":"0.00","stock":100,"visible":1}}' \ "$PAYDRO_ORIGIN/$EVENT_ID/products/add/free.json" ``` Use an event's existing category or explicitly submit `category_id`/`category_new`. Read [product management](https://developer.paydro.com/en-us/docs/product-management.md) before executing this example. Examples in the reference use synthetic IDs: replace them with IDs from your authorized event. ## Recognize success {#recognize-success} | Action family | Success condition | | --- | --- | | Products, promo codes, order lifecycle | `ok === true`; creation can include `id` or `event_id`. | | Waiting-list invitations/settings | `status.success === true`. | | Files | `success === true`. | | Notes | JSON boolean `true`. | | Product/question ordering | HTTP 204 with no body. | | Category/question creation and legacy question changes | Inspect the documented redirect/form result and re-read definitions or attendee snapshots. | | Check-in | A returned row with `checkedin: 1`; an empty array means no eligible ticket was found. | HTTP 200 alone does not prove success. Product validation can return submitted form data or `[data, error]`. Order actions can return `{error: ...}` with 200. Validate HTTP status, content type and the documented body. Disable automatic redirect following so login or organizer HTML does not appear to be successful JSON. Read [error handling](https://developer.paydro.com/en-us/docs/errors.md) for the authentication and legacy error formats. ## Read before retrying {#read-before-retrying} The API does not publish a general idempotency-key contract. A timeout after sending a write leaves its result uncertain. Re-read the resource or invitation history before retrying. Creation can duplicate records, visibility toggles can reverse state again, and invitation/resend operations can queue another email. Order lifecycle replay guards apply only to their individual operations. Apply writes one at a time when they depend on each other. Preserve the event relationship, follow any returned replacement order ID, and refresh affected records after success. Do not retry invalid credentials, foreign IDs or validation errors without correcting the request. ## Understand the contract boundary {#understand-the-contract-boundary} The reference describes existing implementation, including its legacy response formats. Successful writes were reviewed in source; documentation discovery exercised synthetic reads and deliberately rejected writes. It did not send invitations, change payment state or check customers in. Test successful writes with synthetic data in your own authorized environment before enabling them. Public waiting-list signup, provider refunds, company promotion forms, stage editing and CSV imports also exist as application workflows. Their HTML/session requirements are described in the relevant guides; no standalone JSON contract is implied by an organizer form or a controller name. --- Source: https://developer.paydro.com/en-us/docs/pagination-and-filtering.md --- description: "Use CakePHP page parameters and the supported resource filters." group: "API fundamentals" order: 8 --- # Pagination and filtering Use CakePHP page parameters and the supported resource filters. The ordinary order and attendee lists use CakePHP page parameters. Bulk snapshot resources use fixed row limits and do not provide cursor pagination. ## Request another page {#request-another-page} Supply the standard `page` query parameter. Start at page 1, process all returned records, and move to the next page. Orders normally return up to 50 rows; attendees return up to 100. ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/$EVENT_ID/orders/index/all.json?page=2" ``` Stop after a short page. A page beyond the last available page can produce a legacy redirect/error instead of a clean empty array. If the final page is exactly full, handle that response explicitly. These lists do not include a standardized total or next cursor envelope. ## Choose a filter {#choose-a-filter} Order filters in the path include `all`, `recent`, `failed`, `pi` (paid invoices), `upi` (unpaid invoices), `op` (online payments), `nco` (not cancelled), `co` (cancelled), `unfinished`, and `reservation`. Attendee filters include `index`, `recent`, and `deleted`. Add `include=scan` for scan status. Product and promocode filters require a second ID segment; use the exact operation path when your integration needs them. ## Know the bulk limits {#know-the-bulk-limits} Order snapshots cap the combined accessible order history at 75,000 rows, ordered by order creation descending. Attendee snapshots cap each event at 10,000 rows. These responses have no next cursor. Use paginated reads for larger datasets and contact support before relying on a snapshot near its cap. --- Source: https://developer.paydro.com/en-us/docs/errors.md --- description: "Check HTTP status and legacy response bodies before processing data." group: "API fundamentals" order: 9 --- # Handling errors Check HTTP status and legacy response bodies before processing data. Paydro’s existing JSON resources do not all use one error envelope. Check the HTTP status, content type, and response body before processing a response as a resource. ## Authentication and permissions {#authentication-and-permissions} Incorrect Basic credentials return a legacy `403` with this structure: ```json {"status":403,"title":"Unauthorized","detail":"User name and password combination are incorrect"} ``` Missing credentials can result in a login redirect. Do not automatically follow that redirect and decode the final HTML as JSON. Confirm credentials on the origin and verify the account’s organization and event rights. ## Invalid input {#invalid-input} Invalid event discovery years return `400` and an `error`/`detail` object. Unknown paths can return `404`. Invalid order IDs can return `{"error":"no_valid_id"}` through a legacy redirect response. Treat a recognized error property as failure even when a legacy response status is successful. ## Pagination errors {#pagination-errors} A list page past the end may use a redirect/error response. Stop after a short page, and distinguish an out of range page from an authentication error. Keep the last successfully imported page until the entire import is complete. ## Temporary failures {#temporary-failures} For `429`, honor `Retry-After`. Back off after network errors or server failures. A temporarily unavailable authentication rate limit store can produce `503`. Correct authentication/permission failures before retrying; see [retry guidance](https://developer.paydro.com/en-us/docs/rate-limits-and-retries.md). ## Report a problem {#report-a-problem} Capture the method, path, response status, and timestamp. Sanitize credentials and personal data before sharing logs with [support](https://developer.paydro.com/en-us/support). --- Source: https://developer.paydro.com/en-us/docs/rate-limits-and-retries.md --- description: "Handle authentication throttling and transient failures without duplicate imports." group: "API fundamentals" order: 10 --- # Rate limits and retries Handle authentication throttling and transient failures without duplicate imports. Authentication attempts are protected by rate limits on IP and account subjects. The API does not publish a general requests per second quota; an absent quota is not a guarantee of unlimited capacity. ## Honor throttling {#honor-throttling} When a request returns `429`, wait at least the number of seconds in `Retry-After`. Do not immediately retry from another worker. Authentication infrastructure failures can return `503`; treat them as temporary failures rather than changing working credentials. ## Retry read requests {#retry-read-requests} For timeouts, temporary network errors, and server errors, retry GET requests using bounded exponential backoff with jitter. For example, begin with one second, then two, four, and eight seconds, and stop after a reasonable number of attempts. Always honor a longer server supplied wait. Do not automatically retry a wrong password, forbidden event, invalid identifier, or malformed input. Fix the request first. Use explicit client timeouts and log sanitized failure metadata. ## Keep imports idempotent {#keep-imports-idempotent} Upsert by UUID and commit a synchronization checkpoint only after applying a complete successful response. A retry must not duplicate orders or attendees. Separate fetch retries from local processing errors. ## Reduce unnecessary work {#reduce-unnecessary-work} For writes, re-read the affected resource before retrying an uncertain result. There is no general idempotency-key contract; creation, visibility toggles and email operations can repeat their side effects. Read [writing data](https://developer.paydro.com/en-us/docs/writing-data.md) for operation-specific success and retry rules. Use snapshot validators, respect caching, and poll at a frequency that suits your workflow. Avoid many concurrent full history requests. Contact support when your data volume approaches the documented snapshot limits. --- Source: https://developer.paydro.com/en-us/docs/events.md --- description: "Find accessible event IDs and retrieve the v2 event resource." group: "Resources" order: 11 --- # Working with events Find accessible event IDs and retrieve the v2 event resource. Events are the starting point for event scoped products, orders, and attendees. Use the event UUID in API paths and the event slug when linking visitors to the public ticket shop. ## Discover events {#discover-events} `GET /events/my.json` returns an `events` array with an `Event` object in each record. It also reports `loaded_years` and `oldest_available_year`. Without a year, the list covers the current and previous year; pass a four digit `year` to request another year. ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/events/my.json?year=2026" ``` The discovery list requires company membership and excludes events whose names contain “test”. Without a year filter, the result is capped at 2,000 events; an explicit year removes that cap. A test event can therefore be accessible by its UUID without appearing in discovery. Keep its ID from the organizer URL. ## Retrieve an event {#retrieve-an-event} ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/api/v2/events/$EVENT_ID" ``` The response has an `Event` object containing fields such as `id`, `name`, `start_date`, `end_date`, `currency`, `timezone`, and shop links. It also includes legacy settings and metadata; use only the fields your integration needs. ## Use public shop links {#use-public-shop-links} The `direct_link` field identifies the visitor facing shop. Do not expose organizer credentials in that link. Check the event’s published state before directing visitors to it. ## Keep event data current {#keep-event-data-current} Refresh event details when displaying dates or links. Treat timezone changes and moved dates as actual changes, and synchronize related records by their stable IDs. ## Create and edit events {#create-and-edit-events} POST `/events/add.json` with an `Event` object to create an event on the authorized company hostname. The server assigns company/defaults and filters protected fields. Supply event name, dates, currency and timezone. Success returns `{"ok":true,"event_id":"..."}`; validation errors can retain legacy HTTP 200 handling. ```curl {"Event":{"name":"Example conference","start_date":"2026-11-20 09:00:00","end_date":"2026-11-20 18:00:00","currency":"EUR","timezone":"Europe/Amsterdam"}} ``` PUT `/{event_id}/events/edit.json` updates allowed `Event` fields and metadata transactionally. Send both dates when changing dates; protected date/sales rules apply. POST `/events/duplicate/{event_id}.json` duplicates authorized configuration and selected related records; waiting-list invitation codes are excluded. Duplicate success returns `id`, rather than `event_id`. ## Change shop status {#change-shop-status} PUT `/{event_id}/events/status/{status}.json` with status `open`, `close` or `sold_out`. Opening can require company clearance. A transition from a concept/test event cleans concept test state transactionally. Success returns `status:200` and updated `Event` context. Aliases `events/open_shop.json`, `close_shop.json` and `sell_out_shop.json` use the same PUT implementation. `GET /{event_id}/dashboard/shop_status.json` returns organizer-facing status messages, rather than an inventory count. Use [product availability](https://developer.paydro.com/en-us/docs/product-availability.md) for capacity and sales-rule interpretation. Use the [complete event/catalog recipe](https://developer.paydro.com/en-us/docs/integration-recipes.md#create-event-catalog) to create categories, questions and ticket products after creating the event. ## Event write fields {#event-write-fields} | Field | Meaning and rules | | --- | --- | | `Event.name` | Non-empty name. Creation starts with a server/company default such as Untitled event; supply your intended name. | | `Event.start_date`, `Event.end_date` | Server-local SQL timestamps. Creation merges server defaults; send deliberate future dates. Send both when changing a schedule. Existing sales and date-protection rules can retain protected dates. | | `Event.currency` | Event currency, such as EUR. Company configuration supplies creation defaults; retain the established currency when editing. | | `Event.timezone` | IANA timezone, such as Europe/Amsterdam. SQL timestamps do not carry an offset; interpret them with the event's configuration. | | `Event.email_name`, `Event.email_mail` | Organizer email sender name/address; company defaults and field validation apply. | | `Event.Meta`, `Meta` | Server-allowlisted metadata. Protected company/provider/security settings are not arbitrary writable keys. Read settings back to confirm permitted changes. | | `Event.company_id`, `Event.id` | Server/route-owned. A creation company mismatch is rejected; use the correct company hostname. | Mutations require company manager/editor or administrator rights. An event edit filters protected fields and is not a guarantee that every submitted setting changed. Follow the returned `event_id` or `id`, then retrieve the event and compare the relevant fields. Shop publication is a separate status operation. ## Full organizer configuration {#full-organizer-configuration} `GET /{event_id}/events/get_event_data.json` returns a broader internal configuration projection with metadata and sensitive settings. Keep it on your server and retain only the fields needed by your integration. Prefer the cleaned v2 event resource for ordinary reads. Review [writing data](https://developer.paydro.com/en-us/docs/writing-data.md) before enabling configuration or status changes. --- Source: https://developer.paydro.com/en-us/docs/ticket-products.md --- description: "Retrieve an event’s ticket products and understand purchased ticket records." group: "Resources" order: 12 --- # Ticket products Retrieve an event’s ticket products and understand purchased ticket records. A product describes something offered by the ticket shop. An attendee’s order line records a purchase of a product. They share a product UUID, but a purchased ticket can retain its original title and price after the product changes. ## List products {#list-products} ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/$EVENT_ID/products/index.json" ``` The response is a JSON array of product objects. Common fields include `id`, `category_id`, `title`, `description`, `price`, `stock`, `visible`, `available_from`, `available_till`, and `package_flag`. Additional pool, package, and metadata information may be present. ## Interpret availability {#interpret-availability} A product’s stock and availability fields describe the current offer. They do not reserve inventory for your integration. Let the Paydro ticket shop validate availability during checkout, particularly when products share pools or belong to packages. Read [product availability](https://developer.paydro.com/en-us/docs/product-availability.md) for computed `current_stock`, unlimited capacity, pending holds, shared-pool usage and sales-window rules. Use [product management](https://developer.paydro.com/en-us/docs/product-management.md) to create, edit, remove and reorder tickets. ## Match purchases {#match-purchases} Match an attendee’s `product_id` or compact `pid` to the product ID. Keep the archived purchased product label when showing historical tickets. A product can be changed or removed while an order line remains relevant. ## Use the shop for sales {#use-the-shop-for-sales} Use [ticket shop embedding](https://developer.paydro.com/en-us/docs/embed-ticket-shop.md) for visitor registration and payment. The reference includes organizer product management; visitor checkout and inventory reservation still use the ticket shop. --- Source: https://developer.paydro.com/en-us/docs/product-management.md --- description: "Create, edit, remove and reorder ticket products, including packages, pricing tiers and shared pools." group: "Resources" order: 13 --- # Product management Manage an event's ticket catalog using its existing product actions. ## Read configuration {#read-configuration} Use `GET /{event_id}/products/index.json` for the catalog and `GET /{event_id}/products/edit/{product_id}.json` for current configuration. The latter includes `Product`, volume/pool/package rows, attachments, metadata and event context. `GET /{event_id}/products/add/free.json` prepares defaults and creates nothing. ## Create a product {#create-a-product} PUT `/{event_id}/products/add/{type}.json` with a `Product` object. Types are `paid`, `free`, `donation` and `package`. Set the corresponding payload fields: free tickets use `price: "0.00"`; donations use `donation: 1`; packages use `package_flag: 1`. The path alone does not populate every submitted flag. ``` {"Product":{"title":"General admission","category_new":"Tickets","price":"0.00","stock":100,"visible":1}} ``` Use an event-owned `category_id`, or `category_new` to create a group with the ticket. If omitted, the action chooses the first existing group. New product IDs and ordering are assigned by the server. Omitted/empty stock becomes `-1` (unlimited); an explicit zero remains zero. Paid tickets require a configured payment provider. The first paid ticket can also update event fee/VAT settings. Successful creation returns `{"ok":true,"id":"..."}`. Validation may return an array containing submitted data and errors with HTTP 200. Read [writing data](https://developer.paydro.com/en-us/docs/writing-data.md) before treating the request as successful. ## Product fields and defaults {#product-fields} | Field inside Product | Validation and meaning | Creation/edit behavior | | --- | --- | --- | | `title` | String, at least 2 characters; permitted HTML is filtered. | Required on creation and full configuration edits. | | `price` | Numeric amount from 0 through 999999.9999 in event currency. Send a decimal string such as `"12.50"`. | Required; free tickets use `"0.00"`. Donations can send null with `donation:1`. | | `category_id` / `category_new` | Event-owned category UUID, or new name of 2–100 characters. | Creation can select the first existing group when both are omitted. Supply one deliberately. Edits require the current category or a new group. | | `stock` | Whole quantity ≥ -1. `-1` means unlimited; 0 means no capacity. | Creation uses -1 when omitted/empty. Send current stock on edit; an empty edit value also becomes -1. This is configured capacity, not computed remaining stock. | | `max_per_sale` | Whole number from 1 through the deployment's `Product.max_per_sale` setting. | Creation uses that setting when omitted/empty. Retain the returned value on edit; do not assume the same maximum in every environment. | | `visible` | 0/1 shop visibility. | Supply deliberately; visibility, sales windows and event state all affect checkout availability. | | `available_from`, `available_till` | Server-local SQL timestamps. | Retain existing values unless changing sales windows. They do not contain a UTC offset. | | `waitinglist`, `keep_soldout_in_shop` | 0/1 waiting-list and sold-out display settings. | Optional; preserve the current flags on full edits. | | `package_flag`, `donation` | 0/1 product modes. | The generic creation path does not assign every mode flag; set the relevant flag explicitly. | | `description`, `text_on_ticket` | Strings; description HTML is filtered. | Optional content; keep the returned configuration when editing another field. | | `duplicate` | 0/1 command flag. | On edit, 1 delegates to creation and can return a new product ID. Omit for an ordinary update. | For an edit, start with `products/edit/{product_id}.json`, map its fields into the write envelopes and retain title, price, category, stock and maximum per sale. The endpoint is a configuration form save rather than a field patch. Volume prices, pool membership and package members are replaced; omitting related selections can clear them. Read [availability](https://developer.paydro.com/en-us/docs/product-availability.md) for computed stock and shared pools. ## Pricing, pools and packages {#pricing-pools-and-packages} Additional top-level envelopes are `ProductsVolume`, `ProductsPool`, `PackagesProduct`, `Meta` and first-paid-ticket `Event` settings. Metadata is limited by server policy. ``` { "Product": {"title":"Bundle","price":"30.00","stock":100,"package_flag":1}, "ProductsVolume": {"5":{"price":"25.00"}}, "ProductsPool": {"1":{"pool":1}}, "PackagesProduct": [{"product_id":"22222222-2222-4222-8222-222222222222","amount":2,"active":1}] } ``` Volume keys are quantities; pool keys identify shared pools. Package rows use event-owned product IDs, positive whole quantities and `active:1` to select a member; rows without an active value are skipped. Do not send the read serializer's pool rows unchanged: submitted pool selections use the keyed structure above. `products/add_package.json` is a PUT alias that forces the package flag; package-mode form/failure rendering still has legacy behavior. ## Edit and delete {#edit-and-delete} PUT `/{event_id}/products/edit/{product_id}.json` with current required configuration and the changes. The route ID is authoritative. Success returns `{"ok":true}`. Setting `Product.duplicate` delegates to creation and can return a new ID. Historical purchases can retain their original product title/price. POST `/{event_id}/products/delete/{product_id}.json` deletes a permitted product. Sold-ticket, package and other references can block deletion. Require `ok:true` and refresh the catalog; don't infer removal from HTTP 200. ## Reorder the catalog {#reorder-the-catalog} PUT `/{event_id}/products/order.json` with a complete `Product` map from category UUID to ordered product UUIDs. Include every category and every product exactly once. An empty group uses `["empty"]`. Success is HTTP 204, without JSON. ``` {"Product":{"55555555-5555-4555-8555-555555555555":["22222222-2222-4222-8222-222222222222"]}} ``` Use [categories](https://developer.paydro.com/en-us/docs/categories.md) and [category questions](https://developer.paydro.com/en-us/docs/ticket-questions.md) for group configuration. The [catalog recipe](https://developer.paydro.com/en-us/docs/integration-recipes.md#create-event-catalog) connects creation and availability reads. --- Source: https://developer.paydro.com/en-us/docs/product-availability.md --- description: "Interpret configured capacity, computed stock, pending holds, shared pools, packages and sales windows." group: "Resources" order: 14 --- # Product availability Read remaining capacity while keeping checkout's full availability rules in view. ## Read current stock {#read-current-stock} `GET /{event_id}/products/index.json` returns a product array with configured `stock` and computed `current_stock`. For a normal finite product, current stock subtracts sold tickets, reservations and pending order holds from configured capacity. Recurring-date and guaranteed-stock rules can change that calculation. ``` [{"id":"22222222-2222-4222-8222-222222222222","title":"General admission","stock":100,"current_stock":72,"pending":3,"visible":1,"waitinglist":1,"ProductsPool":[{"pool":"1","sales":28}]}] ``` Unlimited configured stock is `-1`. Its current computed sentinel is `8388607`; do not display that as literal finite ticket capacity. The list retains `pending`, but removes the separate `times_sold` and `reserved` fields. Don't reconstruct those counts from missing fields. ## Check shared pools {#check-shared-pools} `ProductsPool[].sales` reports shared-pool usage. Event metadata keys `products_pool_{pool_id}` contain configured limits. Products can share a pool, so two individually available ticket types may compete for the same remaining capacity. The organizer catalog includes sold-out products and does not clamp every `current_stock` value to its pool limit. Full organizer configuration is available through `/{event_id}/events/get_event_data.json`, but it includes sensitive internal settings. Read only the metadata you need on your server. Use the organizer's pool settings when configuring limits and verify metadata write rules for your event. ## Consider sales rules {#consider-sales-rules} - `available_from`/`available_till` define sales windows using legacy server-local timestamps. - `visible` controls visitor visibility. - Package component quantities and shared pools can constrain a bundle. - Recurring dates and guaranteed invitation stock have their own capacity rules. - `waitinglist` and `keep_soldout_in_shop` affect visitor shop behavior after sellout. ## Avoid stale promises {#avoid-stale-promises} A read does not reserve stock. Capacity can change between reading and paying. Refresh before displaying availability, treat the result as advisory, and let Paydro validate the visitor's final checkout. There is no separate inventory-hold API in this reference. See [waiting lists](https://developer.paydro.com/en-us/docs/waiting-lists.md) for issuing invitations and [embedding](https://developer.paydro.com/en-us/docs/embed-ticket-shop.md) for completing registration and payment. --- Source: https://developer.paydro.com/en-us/docs/categories.md --- description: "Read, create, update, hide and delete event ticket categories, with their registration question definitions." group: "Resources" order: 15 --- # Categories Organize ticket products into groups with shared registration questions. ## Read categories {#read-categories} `GET /{event_id}/categories/index.json` returns an array of `Category` wrappers with `CategoryField` question definitions. Categories are ordered by `Category.order`. Use category and question UUIDs as keys. Product records use `category_id` to identify their group. ``` [{"Category":{"id":"55555555-5555-4555-8555-555555555555","name":"Tickets","order":0,"hide":0},"CategoryField":[]}] ``` ## Create a category {#create-a-category} `POST /{event_id}/categories/add.json` with `{"Category":{"name":"Workshops"}}`. Names must contain 2–100 characters. The server assigns the event, ID and next ordering position. Creation uses a legacy HTTP 302 redirect to the category list. Its JSON body can contain `{"error":"invalid_request"}` even after a successful save. Keep redirect following disabled and read `categories/index.json` again to find and confirm the new category. Validation failures return HTTP 400 with `ok:false` and `validation_errors`. Read before retrying an uncertain creation to avoid duplicate groups. You can also create a category while [creating a product](https://developer.paydro.com/en-us/docs/product-management.md) using `Product.category_new`. ## Update and hide {#update-and-hide} | Method and path after the event UUID | Behavior | | --- | --- | | `PUT /categories/edit/{category_id}.json` | Submit `{"Category":{"name":"Tickets","order":0}}`. Name is required; only name/order are writable. Require `ok:true`. | | `POST /categories/showhide/{category_id}.json` | Toggle visibility; returns the resulting `hidden` boolean. A repeated request toggles it again. | The route ID and event are authoritative. Missing or foreign categories return HTTP 404. Refresh the list after changes. Product positioning across groups uses the complete [product ordering](https://developer.paydro.com/en-us/docs/product-management.md#reorder-the-catalog) map. ## Delete a category {#delete-a-category} `POST /{event_id}/categories/delete/{category_id}.json` deletes an unused category. The last category and categories containing products are protected with HTTP 409. Require `ok:true` and refresh the list. Category questions are related records; review them before removing a group. ## Manage category questions {#manage-category-questions} Use the [category questions guide](https://developer.paydro.com/en-us/docs/ticket-questions.md) to read, create, edit, remove and reorder definitions. Updating the current definition and refreshing previously purchased ticket snapshots are separate actions. --- Source: https://developer.paydro.com/en-us/docs/ticket-questions.md --- description: "Read and manage category question definitions, order registration questions, and refresh existing ticket snapshots." group: "Resources" order: 16 --- # Category questions Define the registration questions shared by products in a category. ## Read definitions {#read-definitions} `GET /{event_id}/categories/index.json` returns every category with its `CategoryField` array. `GET /{event_id}/category_fields/edit/{category_id}/{question_id}.json` reads one definition in a `CategoryField` envelope. Use question UUIDs as keys and `order` for display order. The `category_fields/view` action has no JSON list view; use the category list. These are current definitions. Purchased attendees can retain historical question snapshots after definitions change. See [categories](https://developer.paydro.com/en-us/docs/categories.md) for managing the parent group. ## Create and update {#create-and-update} | Method and path after the event UUID | Result | | --- | --- | | `PUT /category_fields/edit/{category_id}.json` | Create a definition. HTTP 302 redirects to its organizer edit page with the new question UUID and `success=1`. | | `PUT /category_fields/edit/{category_id}/{question_id}.json` | Edit a definition. HTTP 200 echoes submitted `CategoryField` data with assigned IDs; it has no `ok` flag. | ``` {"CategoryField":{"name":"Dietary preference","type":"text","mandatory":0,"on_ticket":1}} ``` Both writes require `name` (2–255 characters) and `type`. Optional fields are `mandatory`, `options`, `on_ticket`, `selfservice_disabled`, `other` and `answer_amount`. The route assigns the category and question IDs. Use question types available in your organizer editor; company/event settings affect the available choices. Choice types use scalar option labels, such as `["Vegetarian","None"]`. Workshop options use rows with `question` and optional `amount`; paid questions use `{"price":"5.00"}`. Omit options for text questions. Empty option labels are discarded and malformed options are rejected. Validation failures return HTTP 400 with `{"success":false,"error":"validation_failed","errors":{...}}`. Missing or foreign IDs can redirect. Disable redirect following: a creation redirect can carry the generic JSON body `{"error":"invalid_request"}` even after success. Inspect `Location` and re-read the category list to confirm creation or an edit before retrying. ## Remove and reorder {#remove-and-reorder} See [question types and answers](https://developer.paydro.com/en-us/docs/question-types.md) for every accepted definition type, conditional option shapes, Other answers and attendee payloads. The [integration recipes](https://developer.paydro.com/en-us/docs/integration-recipes.md) connect definitions with products and attendee edits. `POST /{event_id}/category_fields/delete/{question_id}.json` removes an event-owned question and compacts ordering. Send `X-Requested-With: XMLHttpRequest` for the JSON branch; otherwise it redirects to the organizer UI. With no request body, success is `[]`. Re-read definitions to confirm removal; historical ticket snapshots can retain the deleted definition. `POST /{event_id}/category_fields/order/{category_id}.json` requires the complete ordered question UUID array in `CategoryField`. Include every current question exactly once. Invalid, foreign or incomplete lists return HTTP 400; success is HTTP 204 without a body. ``` {"CategoryField":["77777777-7777-4777-8777-777777777777"]} ``` ## Refresh existing tickets {#refresh-existing-tickets} `POST /{event_id}/category_fields/update_all_tickets/{category_id}/{question_id}.json` verifies the selected definition and refreshes product/question snapshots for attendees whose products belong to that category. The refresh can include all current category definitions. A successful no-body request returns `[]`; re-read affected attendees to verify the result. This batch is not atomic across all attendees. HTTP 500 can return `{"success":false,"error":"ticket_update_failed","failed_ids":[...]}` after earlier attendees were already updated. Inspect those IDs and current snapshots before retrying. Updating current definitions alone does not rewrite purchased tickets. ## Edit attendee answers {#edit-attendee-answers} Use the [attendee answer and question actions](https://developer.paydro.com/en-us/docs/attendee-management.md) to edit one attendee's answers or archived question snapshot. They enforce attendee ownership and editable order state separately from definition management. --- Source: https://developer.paydro.com/en-us/docs/question-types.md --- description: "Supported category question types, option formats, attendee answer payloads and historical registration data." group: "Resources" order: 17 --- # Question types and answers Match each registration question to its definition and answer format. Create definitions with `CategoryField` through [category questions](https://developer.paydro.com/en-us/docs/ticket-questions.md). Submit answers under their question UUID inside `OrderLine` through [attendee management](https://developer.paydro.com/en-us/docs/attendee-management.md). Definition options and attendee answers have different shapes. ## Supported types {#supported-types} | Definition type | Definition options | Attendee answer | | --- | --- | --- | | `text`, `organization`, `branche`, `job_description`, `textarea` | Omit options. | String. The named types are text presets. | | `numeric` | Omit options. | Numeric text, such as `"12"`. | | `email` | Omit options. | Email string. | | `date` | Omit options. | `"2027-06-20"` in the organizer editor. | | `time` | Omit options. | `"09:30"`. | | `dateTime` | Omit options. | `"2027-06-20T09:30"`. Saved as a server-local SQL timestamp; detail converts it back to the editor format. | | `checkbox` | Omit options. | `"1"` checked, `"0"` unchecked. | | `select` | Scalar option labels. | One option label as a string. | | `singlechoice` | Scalar option labels. | Array containing one selected label, or an object for an Other answer. | | `multiplechoice` | Scalar option labels. | Array of selected labels, or an object for an Other answer. `[]` clears a selection. | | `workshop` | Option rows containing `question` and optional `amount`. | The option key as a string, such as `"0"`; preserve returned keys. | | `paid` | `{"price":"5.00"}`; the signed amount represents a charge or discount. | Purchased value/name/options snapshot. The attendee save action preserves it and does not change the charge. | | `donation` | Omit options. | Amount collected by checkout. The organizer editor displays it as read-only; use checkout for financial changes. | | `label` | Omit options. | Display content; no editable answer is needed. | | `file` | Omit options. | Attachment context. Attendee JSON save skips file answers; it is not a file-upload endpoint. | | `day_choice`, `day_indicator` | Event day choices; `day_indicator` can retain scalar options. | A key from the definition's `dayChoices`. Empty day-choice value means not attending that day. | Type names are case-sensitive, including `dateTime`. Company day-choice support and the event's configured days must be enabled for day questions; each category has an event-dependent day-question limit. Historical snapshots can contain `day_choice_hidden`, `radio` or `datetime`; these are not accepted new definition types. Preserve historical data rather than recreating its definition with an unsupported type. ## Definition options {#definition-options} ``` {"CategoryField":{"name":"Dietary preference","type":"multiplechoice","options":["Vegetarian","Gluten free"],"other":1}} {"CategoryField":{"name":"Session","type":"workshop","options":{"0":{"question":"Morning workshop","amount":20},"1":{"question":"Afternoon workshop","amount":15}}}} {"CategoryField":{"name":"Printed programme","type":"paid","options":{"price":"5.00"}}} ``` Choice labels must be scalar strings or numbers; nested choice objects are rejected. Workshop rows only accept `question` and `amount`. Paid options only accept `price`. Empty labels are removed; keys are retained, so a filtered array can return as an object. Re-read definitions after saving and use the returned labels or keys. ## Answer payloads {#answer-payloads} Replace these synthetic UUIDs with question IDs from `order_lines/edit_data`. This example answers a multiple-choice question, a single-choice question and a date/time question. ``` {"OrderLine":{ "77777777-7777-4777-8777-777777777777":["Vegetarian","Gluten free"], "88888888-8888-4888-8888-888888888888":["Morning"], "99999999-9999-4999-8999-999999999999":"2027-06-20T09:30" }} ``` For a question with `other:1`, use the editor's object format. Numeric keys contain selected labels, `choose_other:"other"` selects Other, and `other_value` contains the entered text. ``` {"OrderLine":{"77777777-7777-4777-8777-777777777777":{"0":"Vegetarian","choose_other":"other","other_value":"No nuts"}}} ``` ## Validation and history {#validation-and-history} Definition names require 2–255 characters. `mandatory`, `on_ticket`, `selfservice_disabled` and `other` use 0/1; `answer_amount` configures the question's answer count. Mandatory flags belong to checkout validation. The organizer save path deliberately skips extra-question validation, so validate choices and formats against the returned definition in your integration. Omitting an answer keeps its stored value; submitting an empty value changes it. Existing attendees can retain different labels/options from the live category. Use their current or historical definitions from detail, preserve paid snapshots, and re-read the saved answers. Updating live definitions and refreshing purchased ticket snapshots are separate operations. --- Source: https://developer.paydro.com/en-us/docs/orders.md --- description: "Read paginated orders, individual order details, and compact snapshots." group: "Resources" order: 18 --- # Working with orders Read paginated orders, individual order details, and compact snapshots. An order groups billing information, payment state, and purchased order lines. Use order IDs as stable keys and keep the event relationship in your own model. ## List event orders {#list-event-orders} ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/$EVENT_ID/orders/index/all.json" ``` The response is an array of records with an `Order` property. The default page size is 50. Event scoped `all` reads are a useful starting point; use the [pagination guide](https://developer.paydro.com/en-us/docs/pagination-and-filtering.md) for later pages and filters. ## Retrieve an order {#retrieve-an-order} ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/$EVENT_ID/orders/view/$ORDER_ID.json" ``` The detail response includes `Order` and related `OrderLine` records. It retains the legacy envelope and can include additional related payment and attachment data. Match an order to the event in the request path. ## Payment state {#payment-state} Use the derived `is_paid` and `payment_state` fields from ordinary order responses. Payment channel, settlement, reservation, refund, and cancellation are separate facts. An accepted invoice can have outstanding payment; a pending refund does not mean that the refund has settled. ## Import many orders {#import-many-orders} `/orders/all_data.json` and `/orders/changed_data.json` return compact event grouped data across accessible companies. Their abbreviated fields and 75,000 row combined limit differ from ordinary order lists. Read [synchronization](https://developer.paydro.com/en-us/docs/synchronizing-data.md) before using them. ## Manage the order {#manage-the-order} Read [order management](https://developer.paydro.com/en-us/docs/order-management.md) for billing edits, reservation confirmation/release, email resends, invoice settlement and eligible cancellation. These actions use the current payment-state capabilities. Invoice/ticket PDFs are described in [Files](https://developer.paydro.com/en-us/docs/files-and-exports.md); CSV/Excel downloads are in [Exports](https://developer.paydro.com/en-us/docs/exports.md). --- Source: https://developer.paydro.com/en-us/docs/order-management.md --- description: "Edit billing data, confirm or drop reservations, resend messages, mark invoices paid, and cancel eligible orders." group: "Resources" order: 19 --- # Order management Use the order's current lifecycle capabilities for organizer actions. ## Read current capabilities {#read-current-capabilities} `GET /{event_id}/orders/detail_data/{order_id}.json` returns `{ok,data}` with organizer context, payment capabilities, pending actions and mail-delivery information. Ordinary order responses also expose `payment_state`. Read them immediately before a dependent write. Provider payment, invoice settlement, reservation, refund and cancellation remain distinct facts. ## Edit an order {#edit-an-order} PUT `/{event_id}/orders/edit/{order_id}.json` with allowed `Order` billing/contact fields and registration answers. The `can_edit` gate and field validation apply. ``` {"Order":{"firstname":"Alex","lastname":"Example","email":"alex@example.com"}} ``` A successful edit can return `{"ok":true}` or a `new_order_created` UUID for a replacement version. Follow the returned ID and refresh related records. Older order revisions, invalid promo codes and validation errors can return legacy JSON errors with HTTP 200. This endpoint does not offer arbitrary payment-state editing. ## Manage reservations {#manage-reservations} | Method and action after `/{event_id}/orders/` | Effect | | --- | --- | | `PUT confirm_reservation/{order_id}.json` | Finalize an eligible reservation; queues customer email by default. | | `PUT resend_reservation/{order_id}.json` | Queue the reservation email again. | | `POST drop_reservation/{order_id}.json` | Drop an eligible reservation through the lifecycle service. | To confirm without queuing mail, include `{"Order":{"dont_email":1}}`. The implementation tests whether that key is present: even `dont_email:0` suppresses mail. Omit it to send. Require `ok:true`; reread the order after completion. ## Invoice and cancellation actions {#invoice-and-cancellation-actions} - PUT `/{event_id}/orders/resend/{order_id}.json` queues an eligible invoice/order email; company clearance can also apply. - PUT `/{event_id}/orders/pay/{order_id}.json` marks an eligible invoice paid through `can_mark_invoice_paid`. It does not force online provider-payment success. - PUT `/{event_id}/orders/cancel/{order_id}.json` cancels an eligible order through `can_cancel`; it can create a credit invoice and notifications. Failures may return `{error: ...}` with HTTP 200. An online provider payment can return `provider_refund_required`. Never treat an order cancellation request as confirmation that money has been refunded. ## Refund and checkout workflows {#refund-and-checkout-workflows} Provider refunds use the organizer's `cancel_refund` and `refund_attendees` workflow, with selections, confirmation, operation state and provider calls. Telesales and duplicate-and-edit checkout also maintain browser/session state. These workflows are not published here as a single stateless JSON refund or order-creation endpoint. Use the organizer UI and [ticket shop](https://developer.paydro.com/en-us/docs/embed-ticket-shop.md) for those flows. See [Files](https://developer.paydro.com/en-us/docs/files-and-exports.md) for invoice/ticket PDFs and [Exports](https://developer.paydro.com/en-us/docs/exports.md) for order CSV/Excel downloads. Successful financial and mail-producing actions were source-reviewed; test them with your approved synthetic/payment environment before enabling them. --- Source: https://developer.paydro.com/en-us/docs/attendees.md --- description: "Read order lines, attendee registration data, and check-in status." group: "Resources" order: 20 --- # Working with attendees Read order lines, attendee registration data, and check-in status. An attendee is represented by an `OrderLine`. A single order can contain multiple lines and multiple attendees. Keep the order line ID as the attendee key and its product relationship separately. ## List attendees {#list-attendees} ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/$EVENT_ID/order_lines/index/index.json" ``` The response is an array of `OrderLine` records containing names, email, product ID, timestamps, and company information where available. The standard event list uses `index` and returns 100 records per page. It applies the existing confirmed/invoiced order or reservation filters and omits cancelled credit records and package container products. ## Include check-in state {#include-check-in-state} ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/$EVENT_ID/order_lines/index/index.json?include=scan" ``` Add `include=scan` to request a numeric `scanned` flag. This read flag indicates an associated scan. To record attendance, use the authorized POST action in the [check-in guide](https://developer.paydro.com/en-us/docs/check-in.md). ## Retrieve registration fields {#retrieve-registration-fields} `/{event_id}/order_lines/edit_data/{attendee_id}.json` returns `{ok: true, data: {...}}`. Read the attendee from `data.orderLine`, answers from `data.orderLine.answers`, and question definitions from `currentQuestions` and `historicalQuestions`. Registration questions vary by event and product. Match fields by ID and read their names when supplied. ## Bulk imports {#bulk-imports} Compact attendee snapshots group rows by event, use abbreviated names, and cap each event at 10,000 rows. Treat the `deleted_items` delta list as removal IDs. Consult the synchronization guide for cancelled orders, weekly windows, and recovery. ## Manage registration {#manage-registration} Use [attendee management](https://developer.paydro.com/en-us/docs/attendee-management.md) for contact/answer updates, eligible product changes, archived question actions and ticket resends. Each operation retains event ownership, order-state and validation checks. --- Source: https://developer.paydro.com/en-us/docs/attendee-management.md --- description: "Edit attendee contact fields and answers, change products, manage archived questions, and resend tickets." group: "Resources" order: 21 --- # Attendee management Update registration data while preserving event and order relationships. ## Read before editing {#read-before-editing} Read `/{event_id}/order_lines/edit_data/{attendee_id}.json` for the current attendee, answers, question definitions and order/product context. A purchased attendee has an archived question snapshot; changing a live product definition does not automatically rewrite it. Order payment state determines whether editing is allowed. ## Save contact fields and answers {#save-contact-fields-and-answers} PUT `/{event_id}/order_lines/save/{attendee_id}.json` with `OrderLine`. Writable contact fields are `title`, `firstname`, `lastname`, `email` and `phone`. Answers use allowed current/historical question UUIDs as keys inside that same object. ``` {"OrderLine":{"firstname":"Alex","lastname":"Example","email":"alex@example.com","77777777-7777-4777-8777-777777777777":"Vegetarian"}} ``` Replace the example question UUID with a question supplied by attendee detail. File answers are skipped by this edit path. A submitted `id` must match the route. Success is `{"ok":true,"data":{"id":"..."}}`; validation uses 400, missing/inaccessible attendees 404, and non-editable orders 409. ## Attendee write fields {#attendee-write-fields} [Question types and answers](https://developer.paydro.com/en-us/docs/question-types.md) documents selected-label arrays, Other objects, workshop option keys and date/time strings. Existing paid-question snapshots are preserved by the save action. It deliberately bypasses extra-question validation; validate values against the attendee's returned current/historical definition. Omitted answers keep their stored values. | Writable field inside OrderLine | Rule | | --- | --- | | `id` | Optional; must match the route attendee UUID when supplied. | | `title`, `firstname`, `lastname`, `phone` | Contact strings; send the fields you intend to change. Organizer contact validation still applies. | | `email` | Email string; invalid values return HTTP 400 validation errors. | | Question UUID | Scalar, choice array or Other object according to its definition. Only permitted current/historical IDs are extracted; files and paid snapshots are protected. | | `product_id`, `order_id`, associations | Not writable here. Use the separate eligible-product/change-product action to change tickets. | ## Change the ticket product {#change-the-ticket-product} Read `GET /{event_id}/order_lines/eligible_products.json`, then POST `/{event_id}/order_lines/edit_product/{attendee_id}.json` with `{"OrderLine":{"product_id":"..."}}` and optional `event_date`. The new product must be eligible in the same event. Date, archived question and order-state checks apply; inspect `ok` and refresh attendee detail afterwards. ## Manage archived questions {#manage-archived-questions} POST these actions with the attendee and question UUIDs in the path. They update the attendee's archived registration snapshot and enforce event ownership and editable order state. - `/{event_id}/order_lines/add_question/{attendee_id}/{question_id}.json` adds an applicable question. - `/{event_id}/order_lines/update_question/{attendee_id}/{question_id}.json` refreshes it from the current definition. - `/{event_id}/order_lines/delete_question/{attendee_id}/{question_id}.json` removes it from that attendee. ## Deliver the ticket {#deliver-the-ticket} POST `/{event_id}/order_lines/resend_one_ticket/{attendee_id}.json` to queue an individual ticket email. Delivery depends on the current ticket/order state. Require `ok:true`; don't replay an uncertain request automatically. Organizer detail can report mail-delivery problems, but queue acceptance is not final delivery confirmation. Use [check-in](https://developer.paydro.com/en-us/docs/check-in.md) to record attendance and [exports](https://developer.paydro.com/en-us/docs/exports.md) to download attendee records. --- Source: https://developer.paydro.com/en-us/docs/waiting-lists.md --- description: "List waiting-list entries, read invitation details, invite or remove entries, and configure phone requirements." group: "Resources" order: 22 --- # Waiting lists Turn waiting-list entries into event-scoped invitations. ## List and filter {#list-and-filter} `GET /{event_id}/waitinglists/list_data.json` lists one event; `GET /waitinglists/list_data.json` lists accessible events. Responses contain `items`, `total`, `page` and `events`. Each item includes a `Waitinglist` wrapper, requested product title and invitation expiry where present. Use `q`, company/event UUID filters, `status` (empty, `waiting`, `invited`), `spotlight` (0/1), `sort` (`name`, `email`, `created`, `ticket`), `direction` (asc/desc) and `page`. Page size is 50. Valid excessive pages clamp to the last page; use total to stop paging. Invalid query values are rejected. ## Read an entry {#read-an-entry} `GET /{event_id}/waitinglists/detail_data/{waitinglist_id}.json` returns `item`, `invitation`, `products` and `event`. Invitation product/quantity are read from the linked promo-code association. An entry without an invitation can return an empty invitation array. Missing or malformed IDs return 404. ## Issue invitations {#issue-invitations} PUT `/{event_id}/waitinglists/invite.json` with the selected entry IDs, eligible product and invitation limits. ``` {"Waitinglist":{"ids":["66666666-6666-4666-8666-666666666666"],"product_id_invite":"22222222-2222-4222-8222-222222222222","amount":1,"invite_valid_for_hours":48}} ``` Amount must be 1–50. Accepted validity hours are `0, 24, 48, 72, 168, 336, 744, 1488, 8760`; zero means no expiry. All entries and the invited product must belong to the event. The action creates replacement invitation codes, revokes previous codes and queues email in a transaction. A failed batch rolls back. Read `status.success`: both success and rejection can return HTTP 200. Re-read entry details before retrying an uncertain request; another invitation can replace the prior code and queue another message. Queuing does not prove mail delivery. ## Remove entries {#remove-entries} PUT `/{event_id}/waitinglists/index.json` with `{"Waitinglist":{"delete":true,"ids":["..."]}}`. Deletion also revokes linked invitation promo codes transactionally. Require `ok:true` and refresh the list. ## Settings and exports {#settings-and-exports} PUT `/{event_id}/waitinglists/settings.json` with `{"Meta":{"waitinglist_phone_mandatory":1}}` to require a phone number in the visitor waiting-list form. The result uses `status.success`. CSV and Excel downloads are covered in [Exports](https://developer.paydro.com/en-us/docs/exports.md). ## Visitor signup {#visitor-signup} Visitors join through the ticket shop's `/{event_slug}/waitinglist` form. Its `Waitinglist` fields include product ID, firstname, lastname, email and optional title/phone/donation/date data; the event is assigned and checked by the server. This storefront workflow returns an HTML fragment for AJAX, and does not provide a standalone JSON signup result. Use the [embedded shop](https://developer.paydro.com/en-us/docs/embed-ticket-shop.md) for visitor registration. --- Source: https://developer.paydro.com/en-us/docs/promo-codes.md --- description: "Create and manage event promo codes, read used-code labels, and queue invitations with per-recipient results." group: "Resources" order: 23 --- # Promo codes and invitations Configure event promotions and issue invitations with explicit recipient results. ## Read used-code labels {#read-used-code-labels} `GET /{event_id}/promocodes/all_data.json` and `GET /promocodes/all_data.json` return cached maps from code UUID to visible code, scoped to event or accessible companies. The query includes codes referenced by orders; unused configured codes do not appear. An empty map can serialize as `[]`. Use validators to handle 304 responses. The legacy `promocodes/index.json` list produced malformed JSON during local discovery: PHP notices and HTML appeared despite a JSON content type and HTTP 200. It is excluded from the supported JSON reference. There is currently no advertised full promo-detail catalog endpoint; use the organizer promotion view for that workflow. ## Create and edit {#create-and-edit} POST `/{event_id}/promocodes/add/{type}.json` creates a single code. Types are `products` (product-specific price) and `prd_prct` (percentage, using `Promocode.discount`). Submit `Promocode` plus event-owned `ProductsPromocode` rows. ``` { "Promocode":{"code":"WELCOME","active":1,"stock":100}, "ProductsPromocode":[{"product_id":"22222222-2222-4222-8222-222222222222","active":1,"max":1,"price":"0.00"}] } ``` Code length is at most 25 characters. Other allowed settings include discount, expiry, budget, guaranteed stock, invoice allowance and hiding other products. Product links use `product_id`, `active`, `max` and `price`. A promo link's zero maximum has different semantics from the waiting-list invitation's required 1–50 amount. PUT `/{event_id}/promocodes/edit/{promocode_id}.json` edits an authorized code with the same envelopes. Single-code create/edit success returns `{"ok":true,"id":"..."}`. Validation and save failures have JSON error handling. Batch `code_amount` creation uses a legacy success redirect and is not part of this single-code result contract. ## Activate or remove {#activate-or-remove} PUT `/{event_id}/promocodes/activate/{promocode_id}.json`, `deactivate/{promocode_id}.json` or `delete/{promocode_id}.json`. Referenced codes can be protected from deletion. Inspect `ok`/`error` even on HTTP 200. Bulk deletion and company-wide promotion forms retain separate legacy rendering and need their own response verification. ## Invite recipients {#invite-recipients} Read `GET /{event_id}/promocode_invites/view/{promocode_id}.json` for `MailQues` history (up to 500 rows), `limit` and `remaining`. POST `/{event_id}/promocode_invites/add/{promocode_id}.json` with recipient rows. ``` {"invites":[{"firstname":"Alex","lastname":"Example","email":"alex@example.com"}]} ``` Firstname and a valid email are required. At most 100 recipients are accepted per request; duplicate email addresses are rejected. An organization awaiting clearance can have a three-invitation organization-wide allowance. The result contains `status` (`ok`, `partial`, `error`), `queued`, `queued_indices`, `rejected`, `message`, `limit` and `remaining`. Rejected rows have an index/reason. Correct and resend only rejected rows; don't resend recipients already queued. A wholly rejected validation request can return 422 and a storage failure 500. Queue acceptance does not prove delivery. For invitations linked to waiting-list entries, use [waiting-list invitations](https://developer.paydro.com/en-us/docs/waiting-lists.md) so prior invitation codes and entry links are updated together. ## Company and batch workflows {#company-and-batch-workflows} The [coverage table](https://developer.paydro.com/en-us/docs/api-coverage.md#organizer-workflows) records company-wide promo management, batch creation and full-catalog limits. Create individual event codes when you need a structured returned ID; keep that ID because used-label maps exclude unused codes. --- Source: https://developer.paydro.com/en-us/docs/check-in.md --- description: "Record authorized ticket check-in, interpret repeat scans, remove scans and export attendance." group: "Resources" order: 24 --- # Ticket check-in Record attendance through the active event-scoped check-in action. ## Authenticate the scanner {#authenticate-the-scanner} A server integration can use HTTP Basic for an organizer with access to the event. The existing check-in UI can establish an event-scoped access-code session through its rate-limited exchange. Do not send raw `access_code` to the scan endpoint; that request is rejected. Keep organizer credentials on your server. ## Check in a ticket {#check-in-a-ticket} POST `/{event_id}/acs/scan.json` with `Content-Type: application/json` and `{"scan":"attendee_uuid"}`. The UUID identifies an order line, not the order or product. ``` {"scan":"44444444-4444-4444-8444-444444444444"} ``` A successful matching ticket returns an array like: ``` [{"id":"44444444-4444-4444-8444-444444444444","scanned":false,"checkedin":1}] ``` `scanned` reports whether it was already checked in before this request. `checkedin:1` reports the resulting state. An empty array means no eligible matching ticket was found. Use the response to distinguish first check-in, repeat check-in and no match. ## Handle scan errors {#handle-scan-errors} - 400 `invalid_ticket_id`: missing/malformed UUID. - 403 `authentication_failed`: event access/session missing or raw access code submitted; invalid Basic credentials can use the shared legacy 403 format. - 405: unsupported method; use POST. - 415 `json_required`: incorrect content type. - 500 `scan_failed`: recording failed. Read existing attendee scan state with `include=scan` on the ordinary attendee list. The active endpoint is documented in the reference; retired scanner/scanapi routes are not integration alternatives. ## Remove or export scans {#remove-or-export-scans} POST `/{event_id}/acs/delete.json` with `{"Acs":{"id":"scan_record_id"}}` removes an authorized event scan. This ID identifies the scan record. Its legacy success body has no reliable structured success flag; re-read attendance state afterwards. CSV attendance and no-show downloads are available through `/{event_id}/acs/export_to/csv` and `/{event_id}/acs/noshow_export_to/csv`. See [Exports](https://developer.paydro.com/en-us/docs/exports.md) for handling file responses and personal data. --- Source: https://developer.paydro.com/en-us/docs/analytics.md --- description: "Read traffic totals, recent visits, UTM sources and cities from the organizer analytics projection." group: "Resources" order: 25 --- # Event traffic analytics Bring the event's existing traffic projection into organizer reporting. ## Read traffic {#read-traffic} GET `/{event_id}/traffic_logs/index.json` with organizer authentication and event access. It returns the existing dashboard-oriented projection. | Field | Meaning | | --- | --- | | `totals_last_90_days` | Date/total rows for the recent reporting window. | | `total_last_24_hours` | Recent visit count. | | `last_hour_logs` | Recent domain, UTM source, city, country code and creation time records. | | `top_utm_sources` | Source aggregates. | | `top_cities` | City aggregates. | ## Interpret the projection {#interpret-the-projection} This is the current organizer reporting projection, with legacy timestamps and count representations. It does not publish a generic analytics query language, arbitrary date-range API or a conversion-attribution guarantee. Parse documented stable fields and allow additional fields. ## Handle visitor data {#handle-visitor-data} Keep visit-level data server-side and restrict reporting access to authorized organizers. Prefer aggregated totals where possible, and apply your retention policy. See [privacy and data handling](https://developer.paydro.com/en-us/docs/privacy-and-data.md) and [supporting data](https://developer.paydro.com/en-us/docs/supporting-data.md) for organizer context. --- Source: https://developer.paydro.com/en-us/docs/supporting-data.md --- description: "Read companies and organizer profiles, manage event favorites, and add or edit authorized event, order and attendee notes." group: "Resources" order: 26 --- # Notes and organizer data Use organizer directories and notes to connect event data to your workflow. ## Directories and profile {#directories-and-profile} - `GET /companies/my.json` returns accessible company wrappers under `myCompanies`. - `GET /users/profile.json` returns the authenticated organizer's ID, name, last name, email and photo identifier. - `GET /users/all_data.json` returns a membership-scoped organizer directory using private caching and a legacy projection. These are authorized account data. Keep personal fields private, and don't use a cached directory as a substitute for the server's live permission checks. ## Read and add notes {#read-and-add-notes} GET `/{event_id}/comments/index/{parent}/{parent_id}.json` returns `Comment` and author `User` wrappers. Parent values are `Event`, `Order` and `OrderLine`. Parent UUIDs must be accessible; original order versions can share notes. PUT `/{event_id}/comments/add/{parent}/{parent_id}.json` with `{"Comment":{"comment":"Follow up with the attendee."}}`. Text must contain 2–500 characters after trimming. The server assigns the authenticated author and checks parent/event access. Success is JSON boolean `true`, rather than an `ok` object. ## Edit notes {#edit-notes} PUT `/{event_id}/comments/edit/{comment_id}.json` with the same envelope. Only the note's author can edit it within 15 minutes of creation. The result is a JSON boolean and failures also use HTTP status codes. Refresh the note list after success. ## Bulk event notes {#bulk-event-notes} `GET /comments/all_data/1.json` reads Event notes created before server-local Sunday midnight. `GET /comments/all_data.json` reads Event notes created on or after that boundary. Combine these history/recent partitions for the available snapshot. Both are scoped to companies the organizer belongs to; Order and OrderLine notes are excluded. ``` {"events":{"11111111-1111-4111-8111-111111111111":{"name":"Example event","currency":"EUR","start_date":"2027-06-20 09:00:00"}},"items":{"11111111-1111-4111-8111-111111111111":[{"id":"aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa","ui":"bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb","c":"Prepare the stage","d":"1791446400"}]}} ``` Each `items` key is an event UUID. Compact fields are `id` (note UUID), `ui` (author UUID), `c` (text) and `d` (Unix seconds, potentially a string). Empty maps can serialize as `[]`. Each partition is capped at 75,000 notes, newest first; there is no cursor or deletion-ID feed. Keep each partition's ETag and use `If-None-Match`; HTTP 304 has no body and means retain your cached partition. The server sends private cache headers and Last-Modified. Recent expiry is about one minute; history expiry is next Sunday at 01:00 server time, with earlier invalidation when notes change. Refresh both partitions when the weekly boundary changes, and replace your cached partition on 200 so removals do not linger. ## Event favorites {#event-favorites} GET `/{event_id}/favorites/check.json` reads the current organizer's favorite state. POST `/{event_id}/favorites/switcher.json` with `{"follow":true}` or `false` sets it. Membership is checked, and the response includes `success` and `follow`. ## Other application workflows {#other-application-workflows} See [stage state and live updates](https://developer.paydro.com/en-us/docs/stages.md) for the public state reads/SSE and authenticated state writes. [API coverage and workflow limits](https://developer.paydro.com/en-us/docs/api-coverage.md) explains company promo codes, batch creation, CSV imports, refunds, workshops, exhibitor tools and provider callbacks. --- Source: https://developer.paydro.com/en-us/docs/stages.md --- description: "Read public stage state, replace it as an event editor, and receive server-sent updates." group: "Resources" order: 27 --- # Stage state and live updates Share display state with a stage screen and subscribe to changes. ## Access and state {#access-and-state} Stage reads and streams are public. Anyone with the stage URL can read its state; keep attendee details, credentials and private organizer notes out of this payload. Writes use organizer authentication, company rights of at least 1 and a matching event/stage pair. See [permissions](https://developer.paydro.com/en-us/docs/permissions.md). A stage is a complete client-defined JSON object stored in cache. Its `id` and `event_id` must match the write route and current event. Additional display/session fields are preserved; there is no fixed agenda schema. For a new default stage, use the event UUID as the stage UUID. Other stage IDs must already exist and belong to that event. ## Read a stage {#read-a-stage} | Method and path | Response | | --- | --- | | `GET /stages/load_stage/{stage_id}` | `{"stage":{...}}`. | | `GET /stages/storage/{stage_id}` | The stage object directly. | These paths do not require an event prefix or a `.json` suffix. Missing state returns `{"error":"No stage found"}` with HTTP 200. Check the body, not just the status. ## Write a stage {#write-a-stage} `POST /{event_id}/stages/ce/{stage_id}` initializes or replaces an authorized stage. Submit the whole state under `stage`; success returns `{"status":"ok"}`. ``` curl --fail-with-body --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --request POST --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data '{"stage":{"id":"11111111-1111-4111-8111-111111111111","event_id":"11111111-1111-4111-8111-111111111111","title":"Main stage"}}' \ "$PAYDRO_ORIGIN/$EVENT_ID/stages/ce/$EVENT_ID" ``` `POST /{event_id}/stages/storage/{stage_id}` replaces an existing stage and echoes the submitted state. If it does not exist, the action returns the HTTP 200 error before writing. Both writes replace the complete object; omitted display fields are removed. Re-read state after saving. There is no version precondition or patch merge; coordinate concurrent writers to avoid overwriting each other. ## Receive live updates {#receive-live-updates} `GET /stages/sse/{stage_id}` returns `text/event-stream`. In a browser, use `EventSource` and parse message data as JSON. On a different origin, browser access also depends on the server's CORS policy; prefer a same-origin stage screen or server-side relay. ``` const stream = new EventSource(`/stages/sse/${stageId}`); stream.onmessage = ({ data }) => { const message = JSON.parse(data); if (message.stage) renderStage(message.stage); }; stream.addEventListener('close', () => stream.close()); stream.onerror = () => showConnectionStatus('Reconnecting'); ``` Changed state arrives as `{"stage":{...}}`. Idle messages contain `{"state_not_changed":true}`, or `{"ping":true}` when state is absent. Ignore these heartbeat objects. The server pads frames with whitespace and ends the stream after roughly ten minutes with a named `close` event. To keep a display connected, create a new stream after that event with bounded backoff; close it when the screen is removed. This stream carries stage state and is not an order/payment webhook feed. ## Verification {#verification} State and stream behavior is traced to the stage controller. Authorization tests cover editor access, foreign state and rejected methods. Continuous streaming and concurrent state replacement still require an integration test in your stage environment. Use [synthetic test data](https://developer.paydro.com/en-us/docs/testing.md) for that check. --- Source: https://developer.paydro.com/en-us/docs/files-and-exports.md --- description: "Upload and remove event files, protect bearer download links, and download invoice and ticket PDFs." group: "Resources" order: 28 --- # Files Handle file responses separately from JSON records. ## Upload an event file {#upload-an-event-file} POST `/{event_id}/files/upload.json` using multipart form data and field `data[Event][file_upload]`. Send `Accept: application/json`; let your HTTP client generate the multipart content-type boundary. Company administrator file-management rights are required. Multipart uploads use POST so the PHP/CakePHP request parser can populate the uploaded-file data. ```curl-·-uploads-a-file curl --fail-with-body --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --request POST \ --header 'Accept: application/json' \ --form "data[Event][file_upload]=@$FILE_PATH" \ "$PAYDRO_ORIGIN/$EVENT_ID/files/upload.json" ``` Success includes `success:true`, `attachment_id` and `attachment` (the download URL). Invalid uploads use 400; storage allowance failures use 409. Existing format validation applies. The event's 25,000,000-byte storage allowance is a soft quota: an upload crossing it is accepted, subsequent uploads are blocked. ## Delete and download {#delete-and-download} POST `/{event_id}/files/delete/{attachment_id}.json` removes an event-owned attachment with the same administrator permission. Require `success:true`. General downloads use `https://files.{domain}/attachments/download/{attachment_id}`, with domain `paydro.com` or your configured local development domain. The files service is separate from the organizer origin. Reference samples use `PAYDRO_FILES_ORIGIN` for this operation. These URLs are permanent bearer links: possession of the unguessable UUID grants download access without login. Treat the URL as a secret, share only with intended recipients, and don't publish private attachments in client logs. Deleting the attachment removes its download availability. ## Download order documents {#download-order-documents} GET `/{event_id}/orders/download_invoice/{order_id}` or `/{event_id}/orders/download_tickets/{order_id}` for invoice/ticket PDFs. These customer links also use the bearer model: possession of the unguessable order UUID grants access without login. The server scopes the order to the event in the URL and checks document/payment state. Keep the URLs private. These paths return files, not JSON envelopes. ## Validate file responses {#validate-file-responses} Check HTTP status, `Content-Type` and `Content-Disposition`; access failures can redirect or return HTML. Keep automatic redirect following disabled and avoid treating an HTML error page as a PDF. Restrict access, encrypt storage and apply the retention policy in [privacy and data handling](https://developer.paydro.com/en-us/docs/privacy-and-data.md). CSV and Excel downloads are documented separately in [Exports](https://developer.paydro.com/en-us/docs/exports.md). --- Source: https://developer.paydro.com/en-us/docs/exports.md --- description: "Download event orders, attendees, waiting lists, check-ins and no-shows as authorized CSV or Excel exports." group: "Resources" order: 29 --- # Exports Download event data for reports and offline workflows. ## Export event data {#export-event-data} Use HTTP GET on your authorized organizer origin, with the event UUID before each path. Exports return file bytes and follow the organizer's current export columns and permission checks. | Data | CSV path after the event UUID | Excel path | | --- | --- | --- | | Orders | `/orders/export_to/csv` | `/orders/exportexcel` | | Attendees | `/order_lines/export_to/csv` | `/order_lines/exportexcel` | | Waiting list | `/waitinglists/export_to/csv` | `/waitinglists/exportexcel` | | Check-ins | `/acs/export_to/csv` | Use CSV. | | No-shows | `/acs/noshow_export_to/csv` | Use CSV. | `exportexcel` produces XLSX. The [Exports reference](https://developer.paydro.com/en-us/reference/overview#tag/exports) includes binary response schemas and download examples in cURL, PHP, Node.js and Python. Save the bytes instead of calling a JSON parser. ## Validate downloads {#validate-downloads} Check HTTP status, `Content-Type` and `Content-Disposition`. Access failures can redirect or return HTML. Keep automatic redirect following disabled and reject unexpected content types so an organizer error page is not saved as a spreadsheet. ## Protect exported data {#protect-exported-data} Exports contain personal data. Limit organizer access, store downloads securely and apply the retention policy in [privacy and data handling](https://developer.paydro.com/en-us/docs/privacy-and-data.md). For continuous record updates, use the JSON reads under Orders and Attendees and the [integration guide](https://developer.paydro.com/en-us/docs/synchronizing-data.md). Attachment uploads and invoice/ticket PDF downloads are covered in [Files](https://developer.paydro.com/en-us/docs/files-and-exports.md). --- Source: https://developer.paydro.com/en-us/docs/integration-recipes.md --- description: "Build a complete event catalog, update attendee answers, and issue and track waiting-list invitations." group: "Build an integration" order: 30 --- # Integration recipes Connect documented operations into complete workflows. ## Prepare your environment {#prepare} Run these examples on your server with an authorized synthetic test organization. Set `PAYDRO_ORIGIN` to the company API hostname, and provide `PAYDRO_EMAIL` and `PAYDRO_PASSWORD` through your secret manager. The developer hostname serves documentation. Use Node.js 18 or later for the complete catalog example. This recipe creates configuration; it leaves publication to your organizer workflow. ## Create an event, questions and products {#create-event-catalog} 1. Create an event with future start/end dates. 2. Create a uniquely named category; confirm the legacy creation redirect with a fresh list. 3. Create a text question; read the category again to obtain the assigned question UUID. 4. Create a free ticket linked to that category. 5. Read the product catalog to confirm its configuration and computed availability. Set `EVENT_START` and `EVENT_END` to future server-local SQL timestamps, for example `2027-06-20 09:00:00` and `2027-06-20 18:00:00`. Save this code as a Node `.mjs` file. Category and question creation can return 302 with a misleading generic error body; the helper only permits those expected redirects and the recipe confirms persistence by reading back. ``` const origin = process.env.PAYDRO_ORIGIN; const auth = Buffer.from(`${process.env.PAYDRO_EMAIL}:${process.env.PAYDRO_PASSWORD}`).toString('base64'); if (!origin || !process.env.PAYDRO_EMAIL || !process.env.PAYDRO_PASSWORD || !process.env.EVENT_START || !process.env.EVENT_END) { throw new Error('Set Paydro origin/credentials and EVENT_START/EVENT_END'); } async function request(method, path, body, redirectPath) { const response = await fetch(new URL(path, origin), { method, redirect: 'manual', signal: AbortSignal.timeout(30000), headers: { Authorization: `Basic ${auth}`, Accept: 'application/json', ...(body ? { 'Content-Type': 'application/json' } : {}) }, ...(body ? { body: JSON.stringify(body) } : {}) }); if (response.status === 302 && redirectPath) { const location = new URL(response.headers.get('location'), origin); if (location.origin !== new URL(origin).origin || !location.pathname.startsWith(redirectPath)) { throw new Error('Unexpected creation redirect'); } return; // The next read must confirm the new record. } if (!response.ok || !response.headers.get('content-type')?.includes('application/json')) { throw new Error(`Unexpected Paydro response: ${response.status}`); } const data = await response.json(); if (data.error || data.ok === false || data.status?.success === false) { throw new Error('Paydro rejected the request'); } return data; } const created = await request('POST', '/events/add.json', { Event: { name: 'Integration example', start_date: process.env.EVENT_START, end_date: process.env.EVENT_END, currency: 'EUR', timezone: 'Europe/Amsterdam' } }); if (created.ok !== true || !created.event_id) throw new Error('Event creation not confirmed'); const eventId = created.event_id; const categoryName = `Example tickets ${Date.now()}`; await request('POST', `/${eventId}/categories/add.json`, { Category: { name: categoryName } }, `/${eventId}/categories/index`); let categories = await request('GET', `/${eventId}/categories/index.json`); let category = categories.find(row => row.Category.name === categoryName); if (!category) throw new Error('Category creation not confirmed'); const categoryId = category.Category.id; await request('PUT', `/${eventId}/category_fields/edit/${categoryId}.json`, { CategoryField: { name: 'Dietary preference', type: 'text', mandatory: 0, on_ticket: 1 } }, `/${eventId}/category_fields/edit/${categoryId}/`); categories = await request('GET', `/${eventId}/categories/index.json`); category = categories.find(row => row.Category.id === categoryId); const question = category.CategoryField.find(field => field.name === 'Dietary preference'); if (!question) throw new Error('Question creation not confirmed'); const ticket = await request('PUT', `/${eventId}/products/add/free.json`, { Product: { title: 'General admission', category_id: categoryId, price: '0.00', stock: 20, visible: 1 } }); if (ticket.ok !== true || !ticket.id) throw new Error('Product creation not confirmed'); const products = await request('GET', `/${eventId}/products/index.json`); const product = products.find(row => row.id === ticket.id); if (!product) throw new Error('Product missing from catalog'); console.log({ eventId, categoryId, questionId: question.id, productId: product.id, stock: product.stock, currentStock: product.current_stock }); ``` Keep the returned IDs. A transport failure after creation has an uncertain outcome; read current records before replaying. There is no idempotency key. For paid products, configure the organization's payment provider first and review [product fields](https://developer.paydro.com/en-us/docs/product-management.md). Availability reads do not reserve tickets; checkout owns reservations and payment. ## Update an attendee's answers {#update-attendee-answers} 1. Read `GET /{event_id}/order_lines/edit_data/{attendee_id}.json`. Confirm `ok:true`, the order's edit capability, and the current/historical question definitions. 2. Choose the UUID from that attendee's permitted questions. Format its value using [question types and answers](https://developer.paydro.com/en-us/docs/question-types.md). 3. Save contact fields and UUID-keyed answers; require `ok:true`. 4. Read detail again and compare the returned answer. A changed live definition does not replace historical snapshots automatically. ``` curl --fail-with-body --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --request PUT --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data '{"OrderLine":{"firstname":"Alex","77777777-7777-4777-8777-777777777777":"Vegetarian"}}' \ "$PAYDRO_ORIGIN/$EVENT_ID/order_lines/save/$ATTENDEE_ID.json" ``` Replace the synthetic question UUID. File uploads and purchased paid-question amounts are not changed by this path. HTTP 409 means the order is no longer editable; refresh it and resolve the state before retrying. For a choice question send a selected-label array, not its definition's options array. ## Invite and track waiting-list subscribers {#invite-waiting-list} 1. Read `GET /{event_id}/waitinglists/list_data.json?status=waiting` and select entries in the same event. 2. Read each `waitinglists/detail_data/{waitinglist_id}.json` and the product catalog. Confirm the eligible product, current invitation and quantity. 3. PUT the invitation body below to `/{event_id}/waitinglists/invite.json`. Require `status.success:true`, including when HTTP is 200. 4. Re-read each detail and inspect the returned invitation/expiry. Queue acceptance is distinct from final email delivery and a completed order. 5. Read the order list when reconciling conversions. Match the resulting order's promo-code ID when present; an invitation code alone does not prove a purchase. ``` {"Waitinglist":{ "ids":["66666666-6666-4666-8666-666666666666"], "product_id_invite":"22222222-2222-4222-8222-222222222222", "amount":1,"invite_valid_for_hours":48 }} ``` Amount is 1–50; allowed hours are 0, 24, 48, 72, 168, 336, 744, 1488 and 8760. Zero means no expiry. Invitations create replacement promo codes and queue email in a transaction. An uncertain retry can revoke the prior code and queue another message, so read details before replaying. Visitor signup happens through the ticket shop, not this organizer endpoint. ## Verify and maintain {#verify-and-maintain} Test validation errors, foreign IDs, empty answers and uncertain outcomes alongside success. Read the [permissions matrix](https://developer.paydro.com/en-us/docs/permissions.md), [verification boundaries](https://developer.paydro.com/en-us/docs/testing.md) and [workflow limits](https://developer.paydro.com/en-us/docs/api-coverage.md). Use the [reference](https://developer.paydro.com/en-us/reference/overview) for all four language samples and exact response formats. --- Source: https://developer.paydro.com/en-us/docs/synchronizing-data.md --- description: "Combine full snapshots, weekly changes, and deletion identifiers safely." group: "Build an integration" order: 31 --- # Synchronizing data Combine full snapshots, weekly changes, and deletion identifiers safely. Use stable IDs and idempotent upserts so repeated imports produce the same local result. Bulk data is optimized for the existing organizer application; its changes cover the current week from Sunday midnight in the server timezone, not the last seven days or a durable stream of events. ## Start with a snapshot {#start-with-a-snapshot} Read `/orders/all_data.json` for compact order history. Read `/{event_id}/order_lines/all_data/2.json` for an event’s attendee history. Store the scope, IDs, and payload in one successful local transaction before treating the import as complete. ```curl curl --user "$PAYDRO_EMAIL:$PAYDRO_PASSWORD" \ --header 'Accept: application/json' \ "$PAYDRO_ORIGIN/$EVENT_ID/order_lines/all_data/2.json" ``` ## Apply changed records {#apply-changed-records} Poll the matching `changed_data` resource. Changes include records modified since Sunday midnight in the server timezone; pending payment actions can also keep orders in the result. The weekly boundary resets the window, so recovering after a missed window requires a new full import. Attendee changes check both order and order line modification dates. A global attendee snapshot covers events starting within the last two years; use the event scoped form for an older event. ## Apply removals {#apply-removals} Delta responses contain `deleted_items`, a list of order or order line IDs from the existing deletion tracking. Cancelled attendee IDs are also collected for recent cancelled orders. Remove matching local records by ID, not by a name or email. Periodically reconcile a full paginated view; the delta is not an indefinite deletion audit log. ## Use HTTP caching {#use-http-caching} Save `ETag` and send `If-None-Match` on subsequent requests to supported snapshot resources. A `304` has no new payload; keep your previous data. Validators belong to the same origin, credentials, and exact path. Honor compression and cache headers. ## Handle compact maps {#handle-compact-maps} Attendee responses are event keyed objects with `event`, `orderlines`, and `products`. Orders contain separate `events` and `orders` maps plus `event_ids` and `event_scope`. Reset cached data when the event scope changes. Respect the [snapshot limits](https://developer.paydro.com/en-us/docs/pagination-and-filtering.md). --- Source: https://developer.paydro.com/en-us/docs/api-coverage.md --- description: "Choose documented JSON resources, identify organizer-only workflows, and understand API coverage and compatibility." group: "Build an integration" order: 32 --- # API coverage and workflow limits Choose the integration surface that matches your workflow. ## Documented resources {#documented-resources} The [OpenAPI reference](https://developer.paydro.com/en-us/reference/overview) covers organizer event configuration, products and availability, categories/questions, order and attendee actions, waiting-list administration, event promo codes/invitations, check-in, analytics, notes/directories, files, exports and stage state. Reads, writes, downloads and streams have different success formats and permissions. Use [integration recipes](https://developer.paydro.com/en-us/docs/integration-recipes.md) to connect operations. Public checkout and waiting-list signup use the [ticket shop](https://developer.paydro.com/en-us/docs/embed-ticket-shop.md). Only event detail currently has an explicit `/api/v2` resource; other documented operations use their existing organizer paths. ## Organizer workflows {#organizer-workflows} | Workflow | Current behavior | Integration approach | | --- | --- | --- | | Company-wide promo codes | `/company_promocodes` provides company catalog, forms, activation/deactivation/deletion and CSV download. Creation is POST; edits and state actions accept PUT. Forms redirect and have no dedicated JSON serializers; a success message does not establish a normalized JSON contract. | Use the organizer company promo-code UI. Event-scoped [promo-code operations](https://developer.paydro.com/en-us/docs/promo-codes.md) have published request/response formats. | | Batch promo-code creation | Event creation accepts `code_amount`; the successful batch branch redirects without a structured list of created IDs. Bulk deletion has legacy redirect/message results. | Use the batch organizer workflow. For JSON automation, create individual codes and retain each returned ID. | | Complete promo-code catalog | The legacy event `promocodes/index.json` failed JSON verification. `all_data` only maps codes referenced by orders; unused codes can be absent. | Keep returned creation IDs. The current reference does not offer a dependable full-detail catalog. | | Attendee CSV import | `/{event_id}/imports/attendees` parses `Csv.csv`, previews validation, requires `Csv.ok` and `send_invite` confirmation, then redirects. Optional email creates delivery side effects. | Use the organizer import preview/confirmation. It is not a stateless JSON bulk-create endpoint. | | Barcode-scan CSV import | `/{event_id}/imports/barcodescans` validates pasted CSV and confirms the selected event before importing. | Use the organizer import screen or the documented individual [check-in API](https://developer.paydro.com/en-us/docs/check-in.md). | | Refunds | `orders/cancel_refund` and `refund_attendees` prepare selections and confirmation, use payment capabilities/operation state, and call the payment provider. | Use the organizer refund workflow. Cancellation and a provider refund are separate operations; a cancellation result does not prove that funds were returned. | | Create paid orders, telesales and duplicate checkout | Checkout maintains cart, visitor/session and payment-provider state. | Use the ticket shop or organizer telesales UI. Existing order edits do not provide an arbitrary order-creation API. | | Workshops and exhibitor tools | Registration options, workshop views and exhibitor lead capture have application-specific workflows. | Use published question/attendee resources for registration data; verify a separate contract before automating these UI tools. | ## Callbacks and credentials {#callbacks-and-credentials} Payment-provider callbacks and HubSpot/Mailchimp authorization callbacks serve those providers' protocols. They are not a customer webhook subscription API. The current integration contract uses organizer HTTP Basic; it does not offer self-service API keys, token scopes, Paydro OAuth client registration or an official SDK. The four language samples in the reference are direct HTTP examples. For order/attendee updates, use the documented snapshot/change resources and their recovery rules. [Stage SSE](https://developer.paydro.com/en-us/docs/stages.md) only streams stage display state. A public API for webhook subscriptions, assured API credentials or provider refunds needs implementation and verification before documentation can promise it. ## Compatibility and changes {#compatibility} The OpenAPI document version identifies a documentation revision; it does not version every server route. Read [developer updates](https://developer.paydro.com/en-us/changelog) before changing your integration. Accept extra response fields, preserve UUIDs and historical data, and check legacy error envelopes. There is no published fixed deprecation notice period. Retired scanner actions and inferred generic v2 mutation routes are excluded; use the documented paths. ## Verification boundary {#verification-boundary} Examples are synthetic and schema-validated. Selected reads are checked against local fixtures; isolated controller tests also verify successful note/category writes and persistence. Other successes and side effects are source-reviewed. [Testing your integration](https://developer.paydro.com/en-us/docs/testing.md) separates those checks from mail delivery, payment-provider verification, binary downloads and continuous streams. --- Source: https://developer.paydro.com/en-us/docs/embed-ticket-shop.md --- description: "Add Paydro registration and checkout to your existing website." group: "Build an integration" order: 33 --- # Embed a ticket shop Add Paydro registration and checkout to your existing website. Embed the public ticket shop when you want visitors to register and check out on your website. The embed uses the public event shop URL; it does not use organizer API credentials. ## Choose the event URL {#choose-the-event-url} Copy the published shop link from Paydro. The URL contains your organization host and event slug. Append `?embed=1`, or `&embed=1` if the link already contains a query string. ```html ``` The example uses Tailwind CSS utilities for full width and viewport height. If your website does not use Tailwind, replace these classes with your site’s equivalent iframe sizing rules; otherwise the browser uses its default iframe dimensions. Preserve scrolling and provide a regular link to the shop as an alternative for visitors. ## Customize visible sections {#customize-visible-sections} Existing embed options include `header`, `attendees`, `info`, `social`, `image`, `title`, `date`, and `location`. Use the embed settings offered by your shop configuration and test the resulting URL; options affect presentation rather than API access. ## Test the complete journey {#test-the-complete-journey} Test on mobile and desktop, including form validation, multiple tickets, payment handoff, confirmation, and any return to the embedded shop. Hosted payment providers may navigate outside the frame. Avoid a restrictive iframe sandbox unless you have tested all required capabilities. ## Protect visitor data {#protect-visitor-data} Your page cannot directly read a cross origin iframe’s form fields. Keep any surrounding analytics consistent with your consent policy, and use authenticated server requests when you need registration data in another system. --- Source: https://developer.paydro.com/en-us/docs/hubspot.md --- description: "Connect your Paydro organization to HubSpot and understand event synchronization." group: "Build an integration" order: 34 --- # Connect HubSpot Connect your Paydro organization to HubSpot and understand event synchronization. Paydro provides a HubSpot connection for organizations. An organization administrator authorizes it through a browser OAuth flow. This connection is separate from authentication to the Paydro API. ## Connect your organization {#connect-your-organization} 1. Sign in to Paydro with company administrator access and select the correct organization. 2. Open the organization’s Integrations page and choose the HubSpot connection. 3. Sign in to the appropriate HubSpot account and review the requested access. 4. Return to Paydro and check that HubSpot is shown as connected. Authorization must return through the same authenticated organization context. If you cancel the provider flow or the state expires, restart from Paydro rather than reusing a callback URL. ## Event workflow {#event-workflow} The event Integrations page reports the HubSpot connection. Paydro’s synchronization associates event attendees with a marketing event in HubSpot. The integration is handled by Paydro; an API GET request does not itself run a HubSpot synchronization. ## Check synchronization {#check-synchronization} Verify one authorized test event in the intended HubSpot account and check the contact/event association. Confirm that names and addresses represent the expected attendees. Match contacts using the supported integration behavior and do not assume every custom field is automatically mapped. ## Reconnect and troubleshoot {#reconnect-and-troubleshoot} Use Re-Connect on the company Integrations page when authorization is revoked or the connected account changes. Check administrator access, provider permissions, and event eligibility before reporting a missing event. [Contact support](https://developer.paydro.com/en-us/support) with sanitized event and timing information. --- Source: https://developer.paydro.com/en-us/docs/mailchimp.md --- description: "Choose an audience and configure event subscriber synchronization." group: "Build an integration" order: 35 --- # Connect Mailchimp Choose an audience and configure event subscriber synchronization. Connect Mailchimp from your Paydro organization’s Integrations page. A company administrator completes the OAuth flow and chooses the intended audience. ## Connect and choose an audience {#connect-and-choose-an-audience} 1. Sign in to the correct Paydro organization with company administrator access. 2. Open Integrations, select Mailchimp, and authorize the intended Mailchimp account. 3. Choose an audience and save the organization’s default audience where appropriate. 4. Open the event Integrations page and its Mailchimp settings to verify event specific configuration. ## Verify the contact workflow {#verify-the-contact-workflow} Check a test registration against the intended audience. Audience selection, existing contacts, subscriber status, and event settings affect the result. Do not infer a marketing subscription from the mere presence of an attendee email address. ## Consent and status {#consent-and-status} Respect the visitor’s consent and existing unsubscribe state. Registration for an event is not automatic permission for unrelated marketing. Ensure your Mailchimp account and event questions reflect the contact workflow your organization intends. ## Change or remove the connection {#change-or-remove-the-connection} Use the company Integrations page to reconnect or disconnect Mailchimp. Removing the default audience stops that default synchronization setting; it is distinct from disconnecting the provider account. Check each event after changing the audience. ## Troubleshoot {#troubleshoot} Verify the connection status, selected audience, provider permissions, and contact subscription state. Share a sanitized description of a failing case with [support](https://developer.paydro.com/en-us/support); do not send OAuth tokens or subscriber exports. --- Source: https://developer.paydro.com/en-us/docs/privacy-and-data.md --- description: "Keep personal data and integration credentials under your organization’s control." group: "Ship and maintain" order: 36 --- # Privacy and data handling Keep personal data and integration credentials under your organization’s control. Order and attendee resources can contain names, email addresses, billing details, and custom registration answers. Limit your integration to the fields required for its purpose. ## Minimize stored data {#minimize-stored-data} Map the specific fields your workflow needs rather than retaining every legacy property or complete response. Separate operational IDs from display information. Avoid forwarding payment related metadata or unrelated custom registration answers to another tool. ## Protect credentials and logs {#protect-credentials-and-logs} Store credentials in a server secret manager, send requests over HTTPS, and restrict access to imported data. Exclude passwords, Authorization headers, session cookies, and full attendee response bodies from logs. Operational logs usually need a path, timestamp, status, and correlation information. ## Respect changes and deletions {#respect-changes-and-deletions} Apply deletion IDs and reconcile your own copies periodically. A successful API read is not permission to retain that data indefinitely. Follow your organization’s retention, access, and deletion procedures for data copied outside Paydro. ## Connected services {#connected-services} Before enabling HubSpot or Mailchimp, verify which organization and provider account are connected and which data should be synchronized. Apply the relevant consent and subscriber status rules. ## Review your obligations {#review-your-obligations} Consult your organization’s privacy policy and processing agreements when designing an integration. See [Paydro privacy information](https://paydro.com/en-us/privacy) and use [support](https://developer.paydro.com/en-us/support) for questions about the data exposed by a resource. --- Source: https://developer.paydro.com/en-us/docs/going-live.md --- description: "Check service configuration, access, recovery, and support before launch." group: "Ship and maintain" order: 37 --- # Going live Check service configuration, access, recovery, and support before launch. Use this checklist after your integration works against authorized test data. Make the first production request deliberately and verify its event and organization before enabling unattended imports. ## Configuration and access {#configuration-and-access} - Confirm the production API origin and event UUIDs. - Put credentials in your secret manager and verify the account’s active status and organizer rights. - Use HTTPS and exclude credentials from browser code and logs. - Confirm that provider connections point to the intended HubSpot or Mailchimp account. ## Data and recovery {#data-and-recovery} - Parse the exact envelope and optional fields from the OpenAPI operation. - Preserve UUID strings, decimal money, event currencies, and applicable timezones. - Upsert by ID, apply deletion IDs from supported change responses, and reconcile periodically. - Handle authentication errors, pagination endings, throttling, and transient failures. - Recover with a full import after a missed weekly delta window. - Check data volume against the 75,000 order and 10,000 attendee snapshot limits. - Before retrying a write with an uncertain outcome, re-read the resource. There is no general idempotency-key contract; creations and emails can be repeated. ## Visitor experience {#visitor-experience} For embedded shops, test the actual registration and payment journey on mobile and desktop. Include a direct shop link, ensure form errors remain visible, and verify confirmation and payment handoff. ## Operations {#operations} Set monitoring for failed imports and unexpected drops in returned record counts. Record a sanitized request/status when an import fails. Define who can rotate credentials, change access, and contact [support](https://developer.paydro.com/en-us/support). Keep a version of the OpenAPI contract with your integration and review the [developer changelog](https://developer.paydro.com/en-us/changelog) when updating it.