# Docs - Guides: Run your front door with Agoo - [Guides](/guides): How Agoo fits together, and where to start for your role. - Getting started - [Set up in 30 minutes](/guides/getting-started/quickstart): Create your organisation, add a site, invite two colleagues, pair a kiosk and check yourself in. - [Organisation and sites](/guides/getting-started/organisation): Set up your organisation profile, sites, gates, zones, time zones and opening hours, and understand the Free plan and the Growth trial. - [Invite your team](/guides/getting-started/invite-your-team): Add people one by one or from a CSV file, let them sign in with Google or Microsoft, and choose the right role for each person. - [Your profile and notifications](/guides/getting-started/your-profile): Add your photo, change the name you go by and your contact details, choose how Agoo tells you things, and keep your sign-in safe. - [Unsaved work and drafts](/guides/getting-started/unsaved-work): What you type in the Console is kept as you type, so a power cut, a dropped connection, a crash or a closed tab never loses it. - [Updates from Agoo](/guides/getting-started/announcements): How Agoo tells you about new features, planned maintenance and anything you need to do, in the Console and by email. - [Agoo's status page](/guides/getting-started/status-page): Check whether every part of Agoo is working, follow an incident as it's fixed, see planned maintenance and 90 days of history, and get updates by email. - [Feedback to Agoo](/guides/getting-started/feedback): Tell Agoo's team what works, what doesn't and what you'd like next, see our replies, and choose whether we may contact or quote you. - [Pair a kiosk](/guides/getting-started/pair-a-kiosk): Install the Agoo Kiosk app, pair it to a site and gate with a code from the Console, choose kiosk or guard mode, and lock the tablet to Agoo. - [Go-live checklist](/guides/getting-started/go-live-checklist): Everything to check before real visitors use Agoo, from branding and forms to an offline test and a roll-call drill. - Visitors - [How visits work](/guides/visitors): Walk-ins and invited guests, visitor types, approvals, check-out and the statuses a visit moves through. - [Kiosk check-in](/guides/visitors/kiosk-check-in): What a visitor sees on the kiosk, screen by screen, from the welcome screen to their badge, and how to set up each step. - [Self check-in from posters](/guides/visitors/self-check-in): Let visitors check themselves in on their own phone by scanning the check-in poster at a site's entrance or gate. - [Invitations and passes](/guides/visitors/invitations): Invite guests ahead of time from the Console or the Workspace app, and send them a QR pass by SMS, WhatsApp or email. - [Request a visit](/guides/visitors/request-a-visit): Let people ask to visit from your own page or a QR poster, confirmed by a code to their phone or email, with the host approving before any pass is sent. - [Details and documents before the visit](/guides/visitors/before-the-visit): Visitors answer your questions and accept or sign your documents on their pass before they arrive, so the desk only has to say hello. - [Documents to sign](/guides/visitors/documents): Your privacy notice, NDAs, waivers and site rules, accepted or signed before or at the visit, with fixed versions, re-sign rules and a signed PDF copy for the visitor. - [Multi-day passes and pass rules](/guides/visitors/multi-day-passes): One pass for several days with daily hours and re-entry, and rules for when and where a pass admits, with defaults per visitor type and an override at the desk. - [Signed passes and offline checks](/guides/visitors/signed-passes): Every pass carries a code signed with your organisation's own key, so a kiosk or guard can check it with no network. How it works, and how to replace the key. - [Wallet passes](/guides/visitors/wallet-passes): Visitors add their pass to Apple Wallet or Google Wallet with one tap, on every plan. It carries the same QR code, shows on the lock screen near your site and keeps itself up to date. - [Host approvals](/guides/visitors/host-approvals): How hosts approve, ask a visitor to wait or decline by push, WhatsApp, SMS link or email, and how delegates and timeouts keep nobody stuck at reception. - [Front desk and guard mode](/guides/visitors/front-desk): Check visitors in and out by hand, use the live on-site register, search and print, look after visitors without a phone, and run the gate in guard mode. - [Check-out](/guides/visitors/check-out): Every way a visit ends, at the kiosk, at the gate, by link or automatically, and how to keep the on-site list accurate. - [Home and reports](/guides/visitors/reports): See today at a glance on Home, then use Reports for any period's visits, busiest times and hosts, and export lists and reports to CSV, Excel or PDF. - [Deliveries](/guides/visitors/deliveries): Log parcels and food deliveries at the kiosk or front desk, notify the recipient, and record who collected what. Includes gate passes for items going in and out. - [Contractors](/guides/visitors/contractors): Keep contractor companies, workers and their documents in one place, run inductions before they arrive, issue multi-day passes and track hours on site. - [Badges](/guides/visitors/badges): Design visitor badges for each visitor type, choose what prints, and reprint a badge when one is lost. - Bookings - [Booking pages](/guides/bookings): Give each kind of meeting its own booking page, so customers, parents, patients and partners pick a time without the back-and-forth. - [Booking types](/guides/bookings/meeting-types): Create booking types with the lengths and ways to meet you offer, in person, by video, by phone or somewhere else, with limits, questions, host confirmation and a waitlist. - [Availability and closed days](/guides/bookings/availability-and-calendars): Set the hours you take bookings, leave out public holidays and your organisation's closed days, and see every booking, request and waitlist in one place. - [Reminders and no-shows](/guides/bookings/reminders-and-no-shows): Send confirmations and reminders by SMS, WhatsApp or email, let guests move or cancel from their booking's page, and track no-shows. In-person bookings become expected visits. - [Put a booking page on your website](/guides/bookings/put-it-on-your-website): Paste one snippet to show a booking page inside your own website, on every plan, and print its QR code for posters. - Attendance - [Attendance](/guides/attendance): Record when staff arrive and leave, by site, and see who is present, late, on leave or absent. - [Clock-in methods](/guides/attendance/clock-in-methods): Choose how staff clock in and out, at the kiosk or on their phone, and what each plan includes. - [Face clock-in](/guides/attendance/face-clock-in): Let staff clock in by face at the kiosk, on the basis your organisation chooses, with a fallback that always works. Never used for visitors. - [Evidence and notices](/guides/attendance/evidence-and-notices): Choose which evidence clock-ins record (face, selfies, location), on what basis, what employees are told, and how long it's kept. - [Shifts and overtime](/guides/attendance/shifts-and-overtime): Set shift patterns, grace periods, breaks and overtime rules so Agoo can flag lateness and count extra hours. - [Leave](/guides/attendance/leave): Let staff request leave from the Workspace app, route it for approval, and keep balances and the attendance board accurate. - [Timesheets and payroll](/guides/attendance/timesheets-and-payroll): Review and approve hours each period, then export them for payroll or sync them with your HR system. - Security and safety - [Watchlist](/guides/security/watchlist): Screen visitors at check-in against your own list of people who need attention, and alert security quietly when there's a match. - [Roll call](/guides/security/roll-call): Account for every visitor, contractor and clocked-in employee during an evacuation or drill, even in a blackout. - [Audit trail](/guides/security/audit-trail): A tamper-evident record of every action in your organisation, with a chain you can verify yourself. - [Roles and permissions](/guides/security/roles-and-permissions): Give each person the access their job needs, by role and, on Growth and above, by site. - [Two-step verification](/guides/security/two-step-verification): Set up an authenticator app so Agoo asks for a six-digit code each time you sign in, step by step for first-timers. - [Agoo support access](/guides/security/support-access): When Agoo staff can see inside your organisation, what they can and can't do, how you're told, and how to end it at any time. - [Account recovery](/guides/security/account-recovery): What happens when someone loses the phone with their authenticator app, how Owners and Admins approve a reset safely, and how an organisation gets a new Owner when its Owner has gone. - [Single sign-on](/guides/security/single-sign-on): Let staff sign in with their Google or Microsoft work account, or your SAML identity provider, and keep accounts in step with SCIM. - Customise - [Branding](/guides/customise/branding): Put your logo, colours and welcome on the kiosk, passes, emails, booking pages and badges, and use your own domain. - [Use your own domain](/guides/customise/own-domain): Put your passes, booking pages and other visitor pages on an address of your own, such as visit.voltabank.example, on Starter and above, with one DNS record and the certificate handled for you. - [Forms and fields](/guides/customise/forms-and-fields): Add your own visitor types and build the questions each one asks, with conditions, per-site questions and privacy rules. - [Notifications](/guides/customise/notifications): Choose how Agoo reaches hosts, staff and visitors, by push, SMS, WhatsApp, email and in-app, with fallbacks, quiet hours and scheduled reports. - [SMS sender ID](/guides/customise/sms-sender-id): Send Agoo's SMS under your organisation's own name, such as VoltaBank, instead of Agoo's. - Organisation groups - [Organisations and groups](/guides/groups): Belong to more than one organisation on one sign-in, and bring organisations together in a group with combined numbers, a shared watchlist, common rules and one bill. - [Lead a group](/guides/groups/lead-a-group): Start a group from Settings → Group, invite organisations by their Agoo address, see their combined numbers, and set the rules every member keeps to. - [Join a group](/guides/groups/join-a-group): Accept or decline an invitation to a group in Settings → Group, choose what the group gets in your organisation, share your watchlist, and leave whenever you like. - [Group billing](/guides/groups/group-billing): The group pays for the organisations it covers on one monthly invoice, a line for each, from the end of what each has already paid. - QR codes - [QR codes](/guides/qr-codes): Make QR codes for posters, menus, desks and staff cards in the Console, with no ads or watermark, and choose plain or tracked codes. - [Codes for people and places](/guides/qr-codes/people-and-places): Staff cards from People, check-in posters for each entrance and gate, directions to a site, and attendance badges, made from the record they're about. - [Design and downloads](/guides/qr-codes/design-and-downloads): Style your QR codes, test that they scan, download them for screens and print, save brand templates and make many codes from a spreadsheet. - [Tracked codes](/guides/qr-codes/tracked-codes): Change where a tracked QR code goes, schedule it, limit or protect it, send devices and countries to different places, and see its scans. - [Your own short-link domain](/guides/qr-codes/own-short-link-domain): On Pro and Enterprise, give new tracked QR codes a short link on your own domain, such as go.voltabank.example/AbC1234, with one DNS record. - [Who makes codes](/guides/qr-codes/who-makes-codes): Choose who in your organisation can make QR codes, give them allowances, approve tracked codes before they go live and ask for brand templates. - Feedback and reviews - [Feedback and reviews](/guides/feedback): Ask visitors how their visit went, follow up the low scores, and, if you choose, earn public reviews on Agoo Reviews from real visits. - [Ask visitors for feedback](/guides/feedback/ask-visitors): Ask once after a visit or booking, by WhatsApp, SMS or email, or from a feedback poster, with questions built in the form builder. - [Results and follow-up](/guides/feedback/results-and-follow-up): Read feedback with honest numbers, get alerts for low scores, follow up and tell the visitor what you did. - [Agoo Reviews](/guides/feedback/agoo-reviews): List your sites on Agoo Reviews, invite reviews from real visits, reply and flag, under rules that are the same for everyone. - Agoo AI - [Agoo AI](/guides/ai): What Agoo AI does, how it protects your data, and how AI credits work on each plan. - [Ask Agoo](/guides/ai/ask-agoo): Ask questions about your visitors, bookings and attendance in plain language and get answers you can check. - [ID and document scan](/guides/ai/id-scan): Point the kiosk at a Ghana Card, passport or other ID and let Agoo fill in the check-in form, with numbers masked and images deleted on your schedule. - [Digitise paper logbooks](/guides/ai/digitise-logbooks): Photograph the pages of your old visitor books and import them into Agoo as searchable visits, after you've checked them. - Hardware - [Hardware](/guides/hardware): The tablets, phones, printers, cards and terminals Agoo works with, how many devices each plan includes, and how to order ready-made kits. - [iPad kiosk](/guides/hardware/ipad-kiosk): Which iPad to use, how to set it up, stands and enclosures, power, and locking it to Agoo with Guided Access or an MDM. - [Android kiosk](/guides/hardware/android-kiosk): Recommended Android tablets and phones for Agoo, kiosk lock-down with screen pinning or a dedicated device, stands and power. - [Badge printers](/guides/hardware/badge-printers): Supported badge and label printers (AirPrint, Brother QL, Zebra and ESC/POS receipt printers), label sizes, setup and troubleshooting. - [NFC and terminals](/guides/hardware/nfc-and-terminals): Use NFC staff cards and tags on the kiosk, plan for attendance terminals, and connect doors, turnstiles and barriers. - [Offline mode](/guides/hardware/offline-mode): What keeps working on the kiosk and guard devices during network and power cuts, how sync works when the connection returns, and how to prepare for dumsor. - Industries - [Churches](/guides/industries/churches): Count every service, welcome first-timers by name, follow up before next Sunday and keep children's church secure. - [Schools](/guides/industries/schools): Control who collects each child, run SHS visiting days without the queue, record late and early slips, and clock staff in. - [Hospitals and clinics](/guides/industries/hospitals): Enforce ward visiting hours and visitor limits, control restricted wards and keep medical reps on appointment, without touching clinical records. - [Estates and gated communities](/guides/industries/estates): Residents invite guests with a one-time code or QR pass, guards verify it at the barrier, and deliveries and domestic staff are handled properly. - Billing - [Plans and limits](/guides/billing/plans-and-limits): The five Agoo plans, their prices in cedis, what each includes, and how trials, VAT and limits work. - [Wallet and credits](/guides/billing/wallet-and-credits): Top up a prepaid cedi wallet for SMS, WhatsApp and AI beyond your plan's monthly allowance. - [Payments](/guides/billing/payments): Pay for Agoo by Mobile Money, card or bank transfer, get VAT invoices and receipts, and know what happens if a payment is late. - Privacy and data - [Data protection](/guides/privacy/data-protection): How Agoo fits Ghana's Data Protection Act, 2012 (Act 843), who is responsible for what, where data is hosted and who processes it. - [Retention and deletion](/guides/privacy/retention-and-deletion): Choose how long Agoo keeps visits, photos, ID images and other data, and how deletion, legal hold and exports work. - [Data subject requests](/guides/privacy/data-subject-requests): How visitors and staff ask to see or delete their data, and how your admins find, export and erase it. - Developers: API, webhooks, MCP, SDKs and plugins - [Developers](/developers): Connect Agoo to your own systems with the REST API, webhooks, SDKs, embeds, a WordPress plugin and an MCP server for AI assistants. - [Make your first API call](/developers/quickstart): Create a test key, list your sites, invite a visitor with an idempotent request, read the visit back, and receive a signed test webhook. - [Authentication](/developers/authentication): Authenticate with secret or publishable API keys for your own integrations, or with OAuth 2.1 and PKCE for apps that other organisations connect. - Concepts - [Environments and test mode](/developers/concepts/environments): Build against a sandbox copy of your organisation with a test key, where no messages are sent and nothing is billed, then switch to a live key. - [IDs, objects and formats](/developers/concepts/ids-and-objects): How Agoo formats IDs, objects, timestamps, time zones, phone numbers and money, and how to read them safely. - [Pagination](/developers/concepts/pagination): Page through any list endpoint with limit and cursor, and fetch every result safely. - [Errors](/developers/concepts/errors): Every Agoo API error is an RFC 9457 problem details object with a stable code. Here is each code, what causes it and what to do. - [Idempotency](/developers/concepts/idempotency): Send an Idempotency-Key with every POST so a retry after a timeout or a dropped connection never invites a visitor or books a slot twice. - [Rate limits](/developers/concepts/rate-limits): How many requests a minute your organisation can make in each mode and plan, the headers that tell you where you stand, and how to back off. - [Versioning](/developers/concepts/versioning): How the Agoo API changes over time, what counts as a breaking change, and how to write an integration that keeps working. - [Passes and pass rules](/developers/concepts/passes): Set when and where a visit's pass admits with pass_rules, check visitors in despite a rule with override_pass_rules, and let them back in on the same pass with re-enter. - [Custom fields](/developers/concepts/custom-fields): Read each organisation's visit types and form schemas, write answers in custom_fields, and handle validation errors. - [Files and uploads](/developers/concepts/files): Upload photos, selfies, signatures and documents straight to Agoo's private storage with short-lived links, then use the file's ID on a record. - Webhooks - [Webhooks](/developers/webhooks): Get a signed HTTPS request the moment something happens in Agoo, such as a visitor checking in, a parcel arriving or a roll call starting. - [Event catalogue](/developers/webhooks/events): Every webhook event Agoo sends, when it fires and what data.object contains, with an example of each. - [Verify signatures](/developers/webhooks/verify-signatures): Check that every webhook really came from Agoo, with complete verification code for TypeScript, Python, PHP and Go, and rotate secrets without downtime. - [Local testing](/developers/webhooks/local-testing): Receive Agoo webhooks on your own machine while you build, with a tunnel, test events, the planned Agoo CLI or requests you sign yourself. - **Tools** - MCP server - [MCP server](/developers/mcp): Let AI assistants such as Claude, ChatGPT, Cursor and VS Code read and act on your Agoo data, within each person's permissions. - [Connect an assistant](/developers/mcp/connect): Add the Agoo MCP server to Claude, Claude Code, ChatGPT, Cursor, VS Code or any client that supports remote MCP servers. - [Tools reference](/developers/mcp/tools): Every tool, resource and prompt the Agoo MCP server offers, with its scope, annotations, inputs and outputs. - [Security and permissions](/developers/mcp/security): How the Agoo MCP server signs people in, limits what assistants can do, records every call and handles personal data. - [Run the local server](/developers/mcp/local-server): Run the Agoo MCP server on your own computer over stdio, authenticated with an API key, for development, test mode and tightly scoped access. - SDKs and tools - [SDKs and tools](/developers/sdks): The official Agoo libraries, components and tools, what each is for, where it runs and its status. - [TypeScript SDK](/developers/sdks/typescript): The official TypeScript and JavaScript library for the Agoo API, for Node.js, Bun, Deno and Cloudflare Workers. - [Webhooks helper](/developers/sdks/webhooks-helper): Verify Agoo webhook signatures and get typed events in TypeScript, with a small package that has no dependencies. - [React components](/developers/sdks/react): Put an Agoo booking widget or visitor pre-registration form in your React or Next.js site, themed to match it. - [Embed script](/developers/sdks/embed): Add an Agoo booking widget or pre-registration form to any website with one script tag and an HTML attribute. - [CLI](/developers/sdks/cli): Use the agoo command to sign in, test webhooks on your own machine, trigger test events, import staff and call any API endpoint. - [Other languages](/developers/sdks/other-languages): The planned PHP library and Python and Go clients, and how to generate a client in any language from the OpenAPI contract today. - WordPress plugin - [WordPress plugin](/developers/wordpress): Agoo for WordPress adds booking and visitor pre-registration to your WordPress site with blocks and shortcodes, and can react to Agoo events. - [Install and connect](/developers/wordpress/install): Install Agoo for WordPress, connect it with your publishable key, and optionally set up the webhook receiver. - [Blocks and shortcodes](/developers/wordpress/blocks-and-shortcodes): Every setting of the Agoo booking and pre-registration blocks and shortcodes, with examples for a church and a clinic. - [Webhooks and hooks](/developers/wordpress/webhooks-and-hooks): How the plugin receives and verifies Agoo webhooks, and the WordPress actions and filters you can use, with PHP examples. - **Connect** - Integrations - [Google and Microsoft calendars](/developers/integrations/calendars): Connect Google Workspace or Microsoft 365 calendars so booking pages respect hosts' real availability, bookings land in their calendars, and meeting invites carry Meet or Teams links. - [Single sign-on and SCIM](/developers/integrations/sso-and-scim): Let staff sign in to Agoo with Google, Microsoft or your SAML identity provider, and create and deactivate their accounts automatically with SCIM. - [Slack and Microsoft Teams](/developers/integrations/slack-and-teams): Send arrival alerts and approval requests to hosts in Slack or Microsoft Teams, and post arrivals to a channel. - [HR and payroll](/developers/integrations/hr-and-payroll): Import staff from a CSV file, export timesheets in payroll-ready formats, and keep Agoo in step with your HR system. - Recipes - [Recipes](/developers/recipes): Complete, working integrations you can copy and adapt, each with test-mode steps and a production checklist. - [Pre-register visitors from your CRM](/developers/recipes/preregister-from-your-crm): When a client meeting is booked in your CRM, create an Agoo visit and send the client a QR pass, keep it in step with changes, and tell the CRM when they arrive. - [A live on-site list in Slack](/developers/recipes/on-site-list-in-slack): Keep one Slack message per site that always shows who is checked in, updated by Agoo webhooks. - [Attendance to payroll](/developers/recipes/attendance-to-payroll): A monthly job that reads every clock-in and clock-out from Agoo and writes a payroll-ready CSV with hours worked, lateness and flags per person per day. - [A booking widget on your site](/developers/recipes/booking-widget-on-your-site): Add online booking to your own website with the embed script, send people to a thank-you page, and have your server told about every booking. - **Reference** - [API reference](/api) - [Changelog](/developers/changelog): Every change to the Agoo API, webhooks and developer tools, newest first. - [Developer support](/developers/support): How to get help with the Agoo API and developer tools, report a security vulnerability, and follow service status and deprecations. - API reference - [API reference](/api): Every endpoint and webhook event of the Agoo REST API, generated from the OpenAPI 3.1 contract. - Organisation: The organisation your key or token belongs to. - [Get the organisation](/api/organisation/get-organisation): Returns the organisation that the API key or access token belongs to, including its plan and prepaid wallet balance. Use it to check which organisation and mode (`livemode`) a key works on. **Scope:** `organisation:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Sites: Your locations, with their gates and paired kiosks. - [List sites](/api/sites/list-sites): Returns your organisation's sites, oldest first. Each site includes its gates and the kiosks paired to it, so one call gives you everything you need to pick a `site_id` or `gate_id`. **Scope:** `sites:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get a site](/api/sites/get-site): Returns one site with its address, time zone, gates and paired kiosks. The site's IANA time zone is the one Agoo uses for that site's days, shifts and summaries. **Scope:** `sites:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - People: Hosts and employees in your directory. - [List people](/api/people/list-people): Returns the hosts and employees in your directory, newest first. Filter by name, email, site or status, for example to find the `host_id` for an invitation. **Scope:** `people:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Create a person](/api/people/create-person): Adds a host or employee to your directory. Give an email address or a phone number (or both) so Agoo can notify them when visitors arrive: with neither, the request returns `validation_failed` at `body.email` and `body.phone`. - Fires `person.created`. - Counts towards your plan's host and attendance limits. Going over a limit returns `plan_required`. - Returns `conflict` if another person already uses the email address. **Scope:** `people:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get a person](/api/people/get-person): Returns one host or employee, including deactivated people. **Scope:** `people:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Update a person](/api/people/update-person): Changes a person's details. Send only the fields you want to change; fields you leave out stay as they are. `custom_fields` are merged key by key, and a key set to `null` is removed. - Fires `person.updated`. - A deactivated person can't be updated (`invalid_state`). - Returns `conflict` if another person already uses the new email address. **Scope:** `people:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Deactivate a person](/api/people/deactivate-person): Deactivates a person instead of deleting them, so their visit and attendance history stays intact. A deactivated person can't host visitors, clock in or sign in, and no longer counts towards your plan's limits. - Fires `person.deactivated`. - Upcoming visits they host keep their `host_id`. Reassign them with `PATCH /visits/{visit_id}`. - Deactivating someone who is already deactivated returns them unchanged and fires no event. **Scope:** `people:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Visits: Invitations, walk-ins and everything that happens to a visit, from expected to checked out. - [List visits](/api/visits/list-visits): Returns visits, newest first. Combine filters to answer everyday questions: - Who is on site now: `status=checked_in&site_id=…` - Today's expected guests: `status=expected&expected_after=…&expected_before=…` - A host's visitors: `host_id=…` In live mode, visits created before your plan's visitor history are left out. They're kept, not deleted, and come back if you move to a plan with a longer history. Visits that are still `expected`, `awaiting_approval` or `checked_in` are always included. **Scope:** `visits:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Create a visit](/api/visits/create-visit): Creates an expected visit: an invitation from a host when you use a secret key or OAuth token, or a pre-registration when you use a publishable key. Agoo links the visit to an existing visitor record when the phone number (or, without a phone, the email address) matches one, and creates a visitor record otherwise. - With `send_pass` (the default), Agoo sends the visitor a QR pass on the channels in `pass_channels`, trying them in order and falling back to the next if one fails. Leave `pass_channels` out to use your organisation's default order. Each message counts towards your SMS and WhatsApp allowance. - Fires `visit.created`, then `pass.sent` once the pass is sent. - The visitor is checked against your watchlist straight away. On a match the visit is held for security (`awaiting_approval`): no pass is sent, no host is asked, `watchlist.matched` fires and your security team is alerted. The response shows only the status. - `type` is one of your organisation's visit type keys (see `GET /visit-types`) and defaults to `meeting`. A key your organisation doesn't have, or a type that is turned off, returns `validation_failed`. - `custom_fields` are checked against the visit form for the visit's `type` (see `GET /forms`). - Pre-registrations made with a publishable key have `source: pre_registration`. If the site requires host approval for pre-registrations, the visit starts as `awaiting_approval`, the host is asked, and the pass is sent once the host approves (the visit is then `expected` again). - Each visitor new this month counts towards your plan's visitors a month. A new visitor beyond it returns `plan_required`; visitors already counted this month can always be invited again. - An unknown `site_id`, or a `host_id` that isn't an active person who can host, returns `validation_failed`. - With a publishable key, `type` must be open for pre-registration (`pre_registration: true` in `GET /visit-types`); any other type, including the default `meeting` when it isn't open, returns `validation_failed` at `body.type`. `custom_fields` may contain only the fields in that type's `public_form`; a field your staff fill in returns `validation_failed` at `body.custom_fields.`. Publishable keys can't list or search people, so your page must already know the `host_id`; to let visitors search for their host, use the hosted pre-registration page (the embed script). - In test mode, messages go to the console's test outbox instead of the visitor. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. **Publishable keys:** allowed, for visit types open for pre-registration. - [Get a visit](/api/visits/get-visit): Returns one visit with its visitor, status and timestamps. In live mode, a visit created before your plan's visitor history returns `plan_required`, and so does any action on it. It's kept, not deleted, and comes back if you move to a plan with a longer history. **Scope:** `visits:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Update a visit](/api/visits/update-visit): Changes a visit's details. Send only the fields you want to change. `custom_fields` are merged key by key, and a key set to `null` is removed. - `site_id`, `host_id`, `type`, `expected_at` and `expected_until` can change only while the visit is `expected`. A new `type` must be turned on for your organisation, and the visit's `custom_fields` must fit that type's form. - `purpose` and `custom_fields` can change while the visit is `expected`, `awaiting_approval` or `checked_in`. - Visits that have ended (`checked_out`, `denied`, `cancelled`, `no_show`) can't change (`invalid_state`). - Fires `visit.updated`. Agoo doesn't message the visitor about the change; call `POST /visits/{visit_id}/resend-pass` to send them an updated pass. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Check a visitor in](/api/visits/check-in-visit): Checks in the visitor on an `expected` visit, for example from your own gate system or reception desk. To record a walk-in from your own system, create the visit first, then check it in. - If the site's rules need host approval, and the host hasn't approved the visit ahead of time, the visit moves to `awaiting_approval`, the host is asked and `visit.approval_requested` fires. Approving the visit then checks the visitor in. - Otherwise the visit moves to `checked_in`, the host is told their visitor has arrived and `visit.checked_in` fires. - The watchlist is checked just as it is at the kiosk. A match holds the check-in for security (`awaiting_approval`), fires `watchlist.matched` and alerts the site's security leads. The host isn't told. - A visit already held for security when it was created records that the visitor has arrived, alerts security and stays `awaiting_approval`. - Any other status returns `invalid_state`. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Let a visitor back in on their pass](/api/visits/re-enter-visit): For a pass that admits again (a multi-day pass, or back in after leaving the same day): a new visit for this entry, tied to the pass's visit (`pass.for_visit_id`) and approved as it was, then checked in as usual. The watchlist runs again and the host is told. - The pass's visit must be `checked_out`, with no entry open. - Its rules must admit now (its days, daily hours, gates and single use). Otherwise `invalid_state`, with an error at `pass_rule.`; set `override_pass_rules` to let the visitor in anyway, which the audit trail records. Never for a cancelled, declined or missed visit. - `visit.created` and `visit.checked_in` fire for the entry. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Check a visitor out](/api/visits/check-out-visit): Checks out the visitor on a `checked_in` visit and fires `visit.checked_out`. Any other status returns `invalid_state`. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Approve a visit](/api/visits/approve-visit): Approves a visit that is `awaiting_approval`. What happens depends on whether the visitor has arrived: - **On site** (they checked in and the host must approve, or they walked in): the visitor is checked in. Fires `visit.approved` and then `visit.checked_in`. Reception sees the decision straight away. - **Not arrived yet** (a pre-registration waiting for the host): the visit is approved ahead of time. It goes back to `expected` with the decision, nobody is checked in, and Agoo sends the visitor their QR pass with the news. Fires `visit.approved`, then `pass.sent` once the pass is sent. When they arrive, checking in doesn't ask the host again. A visit held by a watchlist match returns `invalid_state` until your security team resolves the match. With an OAuth token, `decision.decided_by` is the signed-in person; with an API key it is `null` and the key is recorded in the audit trail. Any other status returns `invalid_state`. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Deny a visit](/api/visits/deny-visit): Denies a visit that is `awaiting_approval` and fires `visit.denied`. Reception is told straight away. A visitor who hasn't arrived yet (a pre-registration) is told the visit can't go ahead. The optional reason is stored on the visit for reception and the audit trail; Agoo doesn't send it to the visitor. Any other status returns `invalid_state`. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Cancel a visit](/api/visits/cancel-visit): Cancels a visit that is `expected` or `awaiting_approval`, so its pass stops working, and fires `visit.cancelled`. With `notify_visitor` (the default), Agoo tells the visitor on the channels their pass was sent on. Any other status returns `invalid_state`. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Resend a visitor's pass](/api/visits/resend-visit-pass): Sends the visitor their QR pass again, for example after they lose the message or you change the visit's times. Only `expected` visits have a pass to resend; any other status returns `invalid_state`. - Leave `channels` out to use the channels the pass was last sent on. - Fires `pass.sent`. Each message counts towards your SMS and WhatsApp allowance. - In test mode, messages go to the console's test outbox. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Visitors: The people who visit you, across all their visits, and erasure under Act 843. - [List visitors](/api/visitors/list-visitors): Returns visitor records, newest first. A visitor record holds one person's details across all their visits; Agoo matches returning visitors by phone number. ID document numbers are never returned in full. In live mode, a visitor whose visits are all hidden by your plan's visitor history is left out. The record is kept, not deleted, and comes back if you move to a plan with a longer history. **Scope:** `visitors:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get a visitor](/api/visitors/get-visitor): Returns one visitor record. To see their visits, call `GET /visits?visitor_id=…`. In live mode, a visitor whose visits are all hidden by your plan's visitor history returns `plan_required`. **Scope:** `visitors:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Erase a visitor](/api/visitors/erase-visitor): Permanently erases a visitor's personal data, for example to act on an erasure request under the Data Protection Act, 2012 (Act 843). This can't be undone. - Agoo removes the visitor's name, contact details, photo, ID document details and custom field answers from the visitor record and all their visits. The visits stay, without personal data, so your counts and the audit trail remain whole. - Fires `visitor.erased`. Later calls for this visitor return `not_found`. - Works on visitors and visits hidden by your plan's visitor history too, so an erasure request is always complete. - Returns `invalid_state` if the visitor is checked in right now or their data is under a legal hold. **Scope:** `visitors:delete` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Deliveries: Parcels received at reception and collected by their recipient. - [List deliveries](/api/deliveries/list-deliveries): Returns deliveries, newest first. Use `status=received` to see parcels still waiting at reception. **Scope:** `deliveries:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Record a delivery](/api/deliveries/create-delivery): Records a parcel received at a site, for example from your own mailroom system. With `notify_recipient` (the default), Agoo tells the recipient by their notification preferences. Fires `delivery.received`. **Scope:** `deliveries:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Mark a delivery as collected](/api/deliveries/collect-delivery): Marks a `received` delivery as collected and fires `delivery.collected`. Leave `collected_by_name` out when the recipient collected it themselves. A delivery that is already collected returns `invalid_state`. **Scope:** `deliveries:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Bookings: Booking types, free slots and the bookings people make. - [List booking types](/api/bookings/list-booking-types): Returns your booking types (the kinds of meeting people can book), sorted by name. With a publishable key, only `public` booking types are returned. Each `public` booking type carries a `public_form`: the intake questions an attendee answers, taken from the visit form of its `visit_type` without the fields your staff fill in. A booking widget renders these. **Scope:** `bookings:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. **Publishable keys:** allowed (public booking types only). - [Get free slots](/api/bookings/get-booking-type-availability): Returns the slots that can be booked for a booking type between two dates, after working hours, Ghana public holidays, buffers, minimum notice, daily caps and existing bookings are taken into account. A `pending` booking holds its slot until the host declines it or it expires. Slots are a snapshot: one can be taken before you book it, which returns `conflict`. The range covers whole days in `time_zone` and can span up to 31 days. **Scope:** `bookings:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. **Publishable keys:** allowed for public booking types. - [List bookings](/api/bookings/list-bookings): Returns bookings, newest first. Filter by booking type, host, status or start time. **Scope:** `bookings:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Create a booking](/api/bookings/create-booking): Books a slot from `GET /booking-types/{btype_id}/availability`. If the slot has been taken in the meantime, you get `conflict`; fetch availability again and offer another time. - If the booking type doesn't require host confirmation, the booking is `confirmed` straight away. Agoo confirms it to the attendee and the host, and sends reminders by your organisation's settings. - If it does (`requires_confirmation`), the booking starts as `pending` and holds its slot. Agoo tells the attendee their request was received and asks the host to confirm or decline it before `confirm_by`. See `POST /bookings/{booking_id}/confirm` and `/decline`. - Fires `booking.created` for every booking, with its `status`. - A confirmed `in_person` booking also creates an expected visit with a QR pass, so the attendee can check in on arrival. Its `visit_id` is set, and `visit.created` and `pass.sent` fire too. For a `pending` booking this happens when the host confirms it. - `custom_fields` are checked against the visit form for the booking type's `visit_type`. With a publishable key, they may contain only the fields in the booking type's `public_form`; a field your staff fill in returns `validation_failed` at `body.custom_fields.`. - Leave `host_id` out to let Agoo pick a free host from the booking type's hosts. - A `booking_type_id` that isn't a booking type you can book (unknown, turned off, or private with a publishable key), or a `host_id` that isn't one of its hosts, returns `validation_failed`. **Scope:** `bookings:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. **Publishable keys:** allowed for public booking types. - [Get a booking](/api/bookings/get-booking): Returns one booking, including the linked visit for confirmed in-person bookings. **Scope:** `bookings:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Reschedule a booking](/api/bookings/reschedule-booking): Moves a `confirmed` booking to another free slot. Agoo tells the attendee and the host, moves the linked visit and fires `booking.rescheduled` (and `visit.updated` for in-person bookings). Returns `conflict` if the new slot isn't free and `invalid_state` if the booking isn't `confirmed`. A `pending` booking can't be moved; confirm or decline it first. **Scope:** `bookings:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Cancel a booking](/api/bookings/cancel-booking): Cancels a `confirmed` booking and its linked visit, frees the slot and fires `booking.cancelled` (and `visit.cancelled` for in-person bookings). With `notify_attendee` (the default), Agoo tells the attendee. Any other status returns `invalid_state`: to turn down a `pending` booking, decline it with `POST /bookings/{booking_id}/decline`. **Scope:** `bookings:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Confirm a booking](/api/bookings/confirm-booking): Confirms a `pending` booking, for booking types that require host confirmation. Agoo tells the attendee it's confirmed, schedules their reminders and fires `booking.confirmed`. For an `in_person` booking it also creates the expected visit with a QR pass, so `visit.created` and `pass.sent` fire too. Returns `invalid_state` if the booking isn't `pending`, for example because it expired or the attendee cancelled it. **Scope:** `bookings:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Decline a booking](/api/bookings/decline-booking): Declines a `pending` booking, frees its slot and fires `booking.declined`. Agoo tells the attendee their request wasn't accepted. The `reason` is kept on the booking for your organisation; the attendee sees it only if you set `share_reason_with_attendee`. Returns `invalid_state` if the booking isn't `pending`. To call off a booking that is already confirmed, cancel it with `POST /bookings/{booking_id}/cancel`. **Scope:** `bookings:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Attendance: Staff clock-ins and clock-outs, daily summaries and shifts. - [List attendance events](/api/attendance/list-attendance-events): Returns clock-ins and clock-outs, most recent first by `occurred_at`. Events recorded offline (during a network or power cut) appear once the kiosk or phone syncs, with their original time and `offline: true`. **Scope:** `attendance:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Record a clock-in or clock-out](/api/attendance/create-attendance-event): Records a clock-in or clock-out from your own terminal, such as a turnstile or a biometric reader you already run. The event's `method` is always `terminal`. - Your terminal can send evidence your organisation has switched on at the site: `selfie_file_id` (a `selfie` file), `location` (with `latitude` and `longitude` only when your organisation keeps coordinates) and `wifi` (with `ssid` and `bssid` only when it keeps them). Evidence that's off returns `validation_failed` at that field. In consent mode, evidence for someone who hasn't consented returns `consent_required`. - Terminal punches must be switched on at the site (they are by default). - Send the time it happened as `occurred_at`. You can send punches late, for example after a network cut; Agoo places them by `occurred_at`. It can't be in the future. - Fires `attendance.clocked_in` or `attendance.clocked_out`, and `attendance.late` when a clock-in is later than the person's shift start plus its grace period. - The person must be active and on attendance (`tracks_attendance: true`); otherwise you get `invalid_state`. **Scope:** `attendance:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get an attendance summary](/api/attendance/get-attendance-summary): Counts, for each day in a range, how many people on attendance were present, late, on leave or absent. Each person counts once per day, in exactly one of the four. Days are whole days in the site's time zone (or your organisation's, without `site_id`). The range can span up to 31 days. **Scope:** `attendance:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [List shifts](/api/attendance/list-shifts): Returns your shift patterns, sorted by name. Shift times are local times in the site's time zone. Agoo uses them, with the grace period, to decide who is late. **Scope:** `attendance:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Review a punch whose face wasn't verified](/api/attendance/review-attendance-event): Accepts or rejects a fallback punch (PIN, QR, NFC or supervisor-assisted) after a failed face match: its `face_check` is `not_verified` and its `review.status` is `pending`. These punches form the review queue (`GET /attendance/events?review_status=pending`) and are counted in the summary until reviewed. - `accepted` keeps the punch. `rejected` voids it: it no longer appears or counts. - A punch that isn't awaiting review returns `invalid_state`. **Scope:** `attendance:manage` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get attendance settings](/api/attendance/get-attendance-settings): Returns how people may clock in across your organisation, the evidence each punch records, the current notice and basis for each evidence type, and how long selfies and coordinates are kept. - **Methods:** `qr` (the kiosk scans a staff QR badge), `rotating_qr` (a phone scans the kiosk's code, which changes every 30 seconds), `pin`, `nfc`, `face` (on a kiosk), `geofence` (a phone inside the site's area) and `terminal` (your own terminal, through the API). At least one is on; sites can change them. A method that's off isn't offered, with one exception: after a failed face match the kiosk offers a fallback (PIN, QR, NFC or a supervisor-assisted punch, method `assisted`), recorded `face_check: not_verified` for review, so nobody is ever locked out. - **Evidence** (face, selfie, location) is off until you switch it on, and each type needs a published notice. Its `basis` is `required` (your organisation requires it under its legal basis; employees acknowledge the notice and capture goes ahead either way) or `consent` (captured only for people who consented). **Scope:** `attendance:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Update attendance settings](/api/attendance/update-attendance-settings): Changes methods and evidence settings, publishes notices and sets how long evidence is kept. Send only what changes. - **Switching evidence on** (`face` or `geofence` in `methods`, or a `selfie_mode` other than `off`) needs a published notice for it, now or before; otherwise `validation_failed` at `body.notices.`. - **Notices:** each one you send becomes a new version with its `basis`, `legal_basis` (for `required`) and `text`. Employees acknowledge (or consent to) the current version. - **Data protection decisions** (notices and retention) need the Data & privacy permission, held by Owners and Admins: keys and OAuth apps get `forbidden`. - At least one method stays on, organisation-wide and at every site; PIN can be off (for example "face only"). The Wi-Fi check is for phone clock-in, so it needs `geofence`. - Methods and evidence your plan doesn't include return `plan_required`. - Switching face off deletes every enrolled face template from your kiosks. **Scope:** `attendance:manage` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get a site's attendance settings](/api/attendance/get-site-attendance-settings): Returns the site's own methods and selfie mode (`null` where it uses your organisation's), its geofence and Wi-Fi networks, and what applies there (`effective`). **Scope:** `attendance:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Update a site's attendance settings](/api/attendance/update-site-attendance-settings): Sets the site's own methods and selfie mode (`null` to use your organisation's again), its geofence (a circle of 20 to 5,000 metres, or a polygon of 3 to 100 points) and the Wi-Fi networks that count as being there. Send only what changes. Switching evidence on at a site needs a published notice for it. **Scope:** `attendance:manage` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [List people's evidence status](/api/attendance/list-attendance-evidence): Returns, for one evidence type, each active person on attendance with their status, sorted by person. Use `status=unacknowledged` for everyone who hasn't acknowledged the current notice yet, or `status=no_consent` in consent mode. **Scope:** `attendance:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get a person's attendance evidence](/api/attendance/get-person-attendance-evidence): Returns, for face, selfie and location evidence, whether it applies to the person and their latest acknowledgement or consent, and the kiosks their face is enrolled on. Face templates stay on the kiosks: Agoo records only where a person is enrolled. People can read their own; reading anyone else's needs `attendance:read`. **Scope:** `attendance:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Record an acknowledgement or consent](/api/attendance/create-person-attendance-evidence): Records that the person acknowledged the current notice (when your organisation requires the evidence) or consented to it (consent mode), for example from a signed paper form or your HR system. Employees usually do this themselves in the app or at the kiosk. - The record's `kind` follows the notice's basis: `acknowledgement` or `consent`. - Recording the same thing again returns the existing record. - With no published notice for the evidence you get `invalid_state`. **Scope:** `attendance:manage` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Withdraw a consent](/api/attendance/withdraw-attendance-evidence): Records that the person withdrew their consent. New capture of that evidence stops straight away, and a method that needs it is no longer offered to them (they use another method, or the kiosk's fallback). For face, every kiosk is told to delete the person's template. Evidence already recorded is kept until its retention date. Acknowledgements can't be withdrawn (`invalid_state`): your organisation requires that evidence. A consent already withdrawn is returned as it is. **Scope:** `attendance:manage` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Watchlist: People your security team wants to be alerted about. - [List watchlist entries](/api/watchlist/list-watchlist-entries): Returns your watchlist entries, newest first. Expired entries aren't returned. **Scope:** `watchlist:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Add a watchlist entry](/api/watchlist/create-watchlist-entry): Adds a person to your watchlist. Give a name and a phone number, an ID number or both. When a visit is created for, or someone checks in as, a person matching an entry (on name, allowing for spelling differences, phone number or ID number), Agoo holds the visit, alerts your security team silently and fires `watchlist.matched`. The visitor, the host and the kiosk aren't told why. Every watchlist read and change is in the audit trail. Leave `site_ids` empty to watch for the person at every site. **Scope:** `watchlist:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Remove a watchlist entry](/api/watchlist/delete-watchlist-entry): Removes an entry from your watchlist. Check-ins stop matching it straight away, and the entry's personal data (name, phone number, ID number hash, reason) is erased. Past matches stay in the audit trail, without them. **Scope:** `watchlist:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Roll calls: Emergency and drill roll calls that account for everyone on site. - [List roll calls](/api/roll-calls/list-roll-calls): Returns roll calls, newest first, with their live counts. Use `GET /roll-calls/{rollcall_id}` for the list of people. **Scope:** `rollcalls:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Start a roll call](/api/roll-calls/start-roll-call): Starts a roll call at a site, for example from your fire alarm panel. Agoo takes a snapshot of everyone on site (checked-in visitors and contractors, and clocked-in employees) and, with `notify` (the default), sends each of them an "I'm safe" link by push, WhatsApp or SMS. Marshals can then account for people in the Workspace app. - Fires `roll_call.started`, then `roll_call.updated` as people are accounted for. - A site can have one active roll call at a time; starting another returns `conflict`. - In test mode, messages go to the console's test outbox. **Scope:** `rollcalls:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get a roll call](/api/roll-calls/get-roll-call): Returns one roll call with everyone in its snapshot and whether they are accounted for. Poll it, or listen for `roll_call.updated`, to show a live board. **Scope:** `rollcalls:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Close a roll call](/api/roll-calls/close-roll-call): Closes an `active` roll call and fires `roll_call.closed`. The final counts and list are kept for your records. A roll call that is already closed returns `invalid_state`. **Scope:** `rollcalls:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Webhooks: Endpoints that receive signed event notifications. - [List webhook endpoints](/api/webhooks/list-webhook-endpoints): Returns the webhook endpoints for the mode of your key, newest first. Live and test mode have separate endpoints. Secrets are never included; they are shown once, when you create or rotate them. **Scope:** `webhooks:manage` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [Create a webhook endpoint](/api/webhooks/create-webhook-endpoint): Registers a URL to receive events. The response includes the endpoint's signing `secret`, **shown only this once**. Store it with your other secrets and use it to verify every delivery. - `url` must be a public HTTPS address, without a user name or password. Its host must resolve, and only to public addresses: Agoo checks when you save it and again before every delivery. Agoo doesn't follow redirects. - List the event types you want in `enabled_events`, or `["*"]` for every type, including types added later, except `watchlist.matched`, which an endpoint receives only by listing it. - An endpoint created with a test key receives test-mode events (`livemode: false`) only. **Scope:** `webhooks:manage` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [Get a webhook endpoint](/api/webhooks/get-webhook-endpoint): Returns one webhook endpoint, without its secret. Check `status` and `disabled_reason` to see whether Agoo has disabled it after repeated failures. **Scope:** `webhooks:manage` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [Update a webhook endpoint](/api/webhooks/update-webhook-endpoint): Changes an endpoint's URL, description or event types, or disables and re-enables it. Send only the fields you want to change. Setting `status` to `enabled` on an endpoint that Agoo disabled after repeated failures turns deliveries back on for new events. **Scope:** `webhooks:manage` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [Delete a webhook endpoint](/api/webhooks/delete-webhook-endpoint): Deletes an endpoint. Agoo stops delivering to it straight away, including pending retries. Events stay available through `GET /events`. **Scope:** `webhooks:manage` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [Rotate an endpoint's secret](/api/webhooks/rotate-webhook-endpoint-secret): Creates a new signing secret, **shown only this once**. For `previous_secret_ttl_hours` (24 by default) Agoo signs every delivery with both the new and the old secret, so the `webhook-signature` header carries two signatures. Deploy the new secret, then let the old one expire. Set `previous_secret_ttl_hours` to `0` to stop using the old secret at once, for example if it leaked. **Scope:** `webhooks:manage` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [Send a test event](/api/webhooks/test-webhook-endpoint): Sends one signed event of the type you choose to the endpoint straight away, with a sample object as `data.object`, and returns the result of that single attempt. Use it to check your signature verification and your response time. - Works on disabled endpoints too, so you can check a fix before re-enabling. - Test events aren't retried and don't appear in `GET /events`. **Scope:** `webhooks:manage` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - Events: Everything that happened in your organisation, as delivered to webhooks. Each event type is documented here. - [List events](/api/events/list-events): Returns events from the last 30 days, newest first. Each event is exactly what was (or would have been) delivered to your webhook endpoints, so you can use this to catch up after downtime. **Scope:** `events:read` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [Get an event](/api/events/get-event): Returns one event from the last 30 days. `data.object` is a snapshot of the object when the event happened; fetch the object itself for its current state. **Scope:** `events:read` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [Redeliver an event](/api/events/redeliver-event): Queues the event for delivery again, to one endpoint or to every enabled endpoint subscribed to its type. Redeliveries carry the same `webhook-id` as the original, so handlers that de-duplicate on it stay safe, and are retried on the usual schedule. Use it after fixing an endpoint that missed events. - An `endpoint_id` must be enabled and subscribed to the event's type (`validation_failed` otherwise). **Scope:** `webhooks:manage` · **Plan:** Growth, Pro and Enterprise in live mode; every plan in test mode. - [visit.created](/api/events/visit-created): A visit is created: an invitation or pre-registration (from the API, the console or the Workspace app), a walk-in at the kiosk, or a confirmed in-person booking. `data.object.source` tells you which. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.created` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visit.updated](/api/events/visit-updated): A visit's details change: site, host, type, times, purpose or custom fields. Status changes fire their own events instead. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.updated` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visit.approval_requested](/api/events/visit-approval-requested): A visit needs a host's decision and Agoo has asked the host (push, WhatsApp, an SMS link or email). The visit is `awaiting_approval`. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.approval_requested` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visit.approved](/api/events/visit-approved): A host, or someone acting for them, approves a visit. If the visitor is on site, `visit.checked_in` follows straight away; if they haven't arrived yet, the visit is `expected` again and `pass.sent` follows once their pass is sent. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.approved` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visit.denied](/api/events/visit-denied): A host, or someone acting for them, denies a visit that was awaiting approval. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.denied` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visit.checked_in](/api/events/visit-checked-in): A visitor is checked in: at the kiosk, by reception or a guard, after an approval, or through the API. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.checked_in` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visit.checked_out](/api/events/visit-checked-out): A visitor is checked out: at the kiosk, by scanning their pass again, by their host or reception, from the check-out link, automatically at the end of the day, or through the API. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.checked_out` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visit.cancelled](/api/events/visit-cancelled): An expected visit, or one awaiting approval, is cancelled. Its pass stops working. Cancelling an in-person booking also cancels its visit. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.cancelled` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visit.no_show](/api/events/visit-no-show): An expected visit's day ends, in the site's time zone, without the visitor checking in. Agoo marks it `no_show`. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visit.no_show` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [pass.sent](/api/events/pass-sent): Agoo sends a visitor their QR pass: when a visit is created with `send_pass`, when you resend it, or when a booking is rescheduled. `data.object` is the visit; `pass.channels` lists where the pass went. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `pass.sent` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [delivery.received](/api/events/delivery-received): Reception, or your system through the API, records a parcel for someone. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `delivery.received` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [delivery.collected](/api/events/delivery-collected): A parcel is collected from reception. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `delivery.collected` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [booking.created](/api/events/booking-created): Someone books a slot, on a booking page, in an embed or through the API. It fires for every booking: `status` is `pending` when the booking type requires host confirmation, and `confirmed` otherwise. Confirmed in-person bookings also fire `visit.created` for the linked visit. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `booking.created` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [booking.confirmed](/api/events/booking-confirmed): The host confirms a `pending` booking: in the console, in the Workspace app, from the link in their confirmation request, or through the API. Bookings that don't need confirmation fire only `booking.created`, with `status: confirmed`. In-person bookings also fire `visit.created` for the visit created now. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `booking.confirmed` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [booking.declined](/api/events/booking-declined): The host declines a `pending` booking. The slot is free again, and the attendee is told their request wasn't accepted. `decline_reason` is for your organisation; the attendee sees it only if the host chose to share it. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `booking.declined` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [booking.expired](/api/events/booking-expired): A `pending` booking wasn't confirmed in time: the confirmation window passed, or the meeting's start time came first (`confirm_by`). The slot is free again, and the attendee is told their request couldn't be confirmed. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `booking.expired` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [booking.rescheduled](/api/events/booking-rescheduled): A confirmed booking moves to a new time, by the attendee's reschedule link, the host or the API. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `booking.rescheduled` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [booking.cancelled](/api/events/booking-cancelled): A booking is cancelled: a confirmed booking by the attendee's cancel link, the host or the API, or a `pending` request by the attendee's cancel link. In-person bookings that had a visit also fire `visit.cancelled`. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `booking.cancelled` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [attendance.clocked_in](/api/events/attendance-clocked-in): An employee clocks in, by any method. Punches made offline fire when the device syncs, with their original `occurred_at`. Evidence appears only when the punch has it: `selfie_file_id`, `location`, `wifi`, and `face_check` with `review`. Agoo never sends face images or templates. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `attendance.clocked_in` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [attendance.clocked_out](/api/events/attendance-clocked-out): An employee clocks out, by any method. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `attendance.clocked_out` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [attendance.late](/api/events/attendance-late): A clock-in is later than the person's shift start plus its grace period. It fires after `attendance.clocked_in` for the same clock-in; `late_minutes` says how late. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `attendance.late` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [watchlist.matched](/api/events/watchlist-matched): Someone checking in matches a watchlist entry. Agoo holds the check-in and alerts your security team silently at the same time; the visitor isn't told. Kiosks also screen while offline. A check-in a kiosk made offline is screened again when it syncs: if Agoo finds a match the kiosk's list didn't have, the visitor is already inside, and the event carries `entered_while_offline: true`. Agoo sends this as a signed `POST` to every enabled endpoint that lists `watchlist.matched` (`*` doesn't cover it). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [roll_call.started](/api/events/roll-call-started): A roll call starts at a site, from the Workspace app, the console or the API. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `roll_call.started` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [roll_call.updated](/api/events/roll-call-updated): Someone is accounted for (by their "I'm safe" link or by a marshal), so the counts change. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `roll_call.updated` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [roll_call.closed](/api/events/roll-call-closed): A roll call is closed. `counts` are final. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `roll_call.closed` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [person.created](/api/events/person-created): A host or employee is added: in the console, by CSV import, by directory sync or through the API. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `person.created` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [person.updated](/api/events/person-updated): A person's details change. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `person.updated` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [person.deactivated](/api/events/person-deactivated): A person is deactivated. Their history stays; they can no longer host, clock in or sign in. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `person.deactivated` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [person.reactivated](/api/events/person-reactivated): A deactivated person is reactivated. They're back in the directory and can host and clock in again; if deactivating them removed their sign-in, it's back too. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `person.reactivated` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - [visitor.erased](/api/events/visitor-erased): A visitor's personal data is erased, through the API, the console or a data subject request. Delete any copy you hold of this visitor's personal data. Agoo sends this as a signed `POST` to every enabled endpoint subscribed to `visitor.erased` (or `*`). Verify the signature, return any `2xx` within 15 seconds, and de-duplicate on `webhook-id`. - Audit: The hash-chained audit trail of who did what, and when. - [List audit events](/api/audit/list-audit-events): Returns entries from your organisation's audit trail, newest first: changes, exports and views of personal data, by people, API keys, OAuth apps, kiosks and Agoo itself. The trail is append-only and hash-chained: each entry's `previous_hash` is the `hash` of the entry before it. Returns entries from your plan's audit-trail period (3 years on Pro, up to 7 years on Enterprise). Moving to a lower plan doesn't delete older entries: they're kept, hidden, and come back when you move up. **Scope:** `audit:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Forms: Your visit types, the JSON Schemas that define your custom fields, and the public forms visitors fill in when they pre-register. - [List visit types](/api/forms/list-visit-types): Returns your organisation's visit types: the six built-in types, renamed or not, and the types your admins have added, such as "Parent pickup" or "Vendor". Built-in types come first, then the others by name. Use a type's `key` as `type` when you create a visit, and its `form_id` to read the questions that type asks. Types that are turned off (`enabled: false`) are included so you can still read older visits; leave them out with `enabled=true`. Types open for pre-registration (`pre_registration: true`) carry a `public_form`: the questions a visitor answers when they pre-register, without the fields your staff fill in. **Scope:** `forms:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. **Publishable keys:** allowed. They see only the types that are turned on and open for pre-registration, so a pre-registration form can offer exactly those. - [Get a visit type](/api/forms/get-visit-type): Returns one visit type by its key, whether it's turned on or off. A key your organisation doesn't have returns `not_found`. A type open for pre-registration includes its `public_form`. **Scope:** `forms:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. **Publishable keys:** allowed for types that are turned on and open for pre-registration. Any other key returns `not_found`. - [List forms](/api/forms/list-forms): Returns your organisation's active forms, each with the JSON Schema for its custom fields. There is one visit form per visit type, including the types your organisation adds, and one person form. Read them to know which `custom_fields` keys and values a visit or person accepts. `GET /visit-types` lists the types. Forms include the fields your staff fill in, so publishable keys can't read them. A pre-registration form gets the visitor's questions from the type's `public_form` in `GET /visit-types` instead. **Scope:** `forms:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get a form](/api/forms/get-form): Returns one form with its JSON Schema. `version` goes up each time an admin publishes a change in the form builder. **Scope:** `forms:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - Files: Photos, ID images, signatures, selfies and documents, uploaded straight to private storage with presigned links. - [Register a file upload](/api/files/create-file): Registers a file and returns a presigned URL to upload it to. Files never pass through the API: send the bytes with `PUT` to `upload.url`, with exactly the headers in `upload.headers`, within five minutes. Then use the file's ID where a record takes one, for example `selfie_file_id` on a clock-in. | `kind` | Content types | Up to | | ---------------- | ----------------------------------------- | ------ | | `visitor_photo` | `image/jpeg`, `image/png`, `image/webp` | 5 MB | | `id_image` | `image/jpeg`, `image/png`, `image/webp` | 10 MB | | `signature` | `image/png` | 1 MB | | `selfie` | `image/jpeg`, `image/webp` | 5 MB | | `delivery_photo` | `image/jpeg`, `image/png`, `image/webp` | 10 MB | | `document` | `application/pdf` | 20 MB | | `badge` | `application/pdf`, `image/png` | 5 MB | - The storage refuses an upload of another type or size, or after the link expires. Register the file again to get a new link. - After the upload, Agoo removes the photo's metadata (EXIF, including any GPS location), checks that the content matches its type and makes a thumbnail for photos. The file's `status` then changes from `pending` to `ready`, usually within seconds. A file whose content doesn't match its type is deleted. - A file that is never uploaded is deleted after a day. ID images, visitor photos and selfies are deleted on your organisation's retention schedule. - `selfie` needs selfie evidence switched on in your attendance settings; otherwise you get `validation_failed` at `body.kind`. **Scope:** `files:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Retrieve a file](/api/files/get-file): Returns a file's details and status. Poll it after uploading to see when the file is `ready`. Selfies are visible only to people who can read attendance, and to whoever uploaded them. **Scope:** `files:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode. - [Get a download link](/api/files/get-file-download): Returns links to a `ready` file and its thumbnail that work for two minutes. Fetch a new link each time you show the file rather than storing one. - Opening an ID image or a selfie is recorded in the audit trail (`file.opened`). - A file that isn't ready yet, or was deleted, returns `invalid_state`. **Scope:** `files:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode.