# Post agentevals Source: https://docs.gleap.io/api-reference/agentevals/post-agentevals https://api.gleap.io/api-docs.json post /agentevals # Create AI content Source: https://docs.gleap.io/api-reference/ai-content/create-ai-content https://api.gleap.io/api-docs.json post /aicontent Create an AI content entry. If an entry with the same contentId already exists in the project it is updated instead. # Delete AI content by batchId Source: https://docs.gleap.io/api-reference/ai-content/delete-ai-content-by-batchid https://api.gleap.io/api-docs.json delete /aicontent/batch/{batchId} Delete all AI content by batchId Remove all AI content entries with the specified batchId # Delete AI content by contentId Source: https://docs.gleap.io/api-reference/ai-content/delete-ai-content-by-contentid https://api.gleap.io/api-docs.json delete /aicontent/{contentId} Delete AI content by contentId Remove an AI content entry by its contentId # Delete old AI content batches Source: https://docs.gleap.io/api-reference/ai-content/delete-old-ai-content-batches https://api.gleap.io/api-docs.json delete /aicontent/oldbatches Delete all AI content except the current batch Remove all AI content entries except those with the current batch ID, optionally filtered by type # Delete YouTube batch content Source: https://docs.gleap.io/api-reference/ai-content/delete-youtube-batch-content https://api.gleap.io/api-docs.json delete /youtube-source/batch/{batchId} Delete all YouTube content from a batch # Delete YouTube video content Source: https://docs.gleap.io/api-reference/ai-content/delete-youtube-video-content https://api.gleap.io/api-docs.json delete /youtube-source/{videoId} Delete a single YouTube video's content # Get AI content by contentId Source: https://docs.gleap.io/api-reference/ai-content/get-ai-content-by-contentid https://api.gleap.io/api-docs.json get /aicontent/{contentId} Get AI content by contentId Retrieve a single AI content entry by its contentId # Import YouTube playlist/channel Source: https://docs.gleap.io/api-reference/ai-content/import-youtube-playlistchannel https://api.gleap.io/api-docs.json post /youtube-source/batch Import a YouTube playlist or channel for bulk AI content analysis # Import YouTube video Source: https://docs.gleap.io/api-reference/ai-content/import-youtube-video https://api.gleap.io/api-docs.json post /youtube-source Import a single YouTube video for AI content analysis # List YouTube content Source: https://docs.gleap.io/api-reference/ai-content/list-youtube-content https://api.gleap.io/api-docs.json get /youtube-source List the project's imported YouTube video content (acknowledged, non-skipped entries), newest first. # Preview YouTube URL Source: https://docs.gleap.io/api-reference/ai-content/preview-youtube-url https://api.gleap.io/api-docs.json post /youtube-source/preview Preview a YouTube URL before importing. Fetches metadata + an exact cost estimate (in cents) for the video or full playlist/channel. For large playlists this can take a few seconds — the client is expected to show a spinner. # Update AI content by contentId Source: https://docs.gleap.io/api-reference/ai-content/update-ai-content-by-contentid https://api.gleap.io/api-docs.json put /aicontent/{contentId} Update an AI content entry by its contentId. If no entry with that contentId exists, one is created (upsert). # Get AI model catalog Source: https://docs.gleap.io/api-reference/aimodels/get-ai-model-catalog https://api.gleap.io/api-docs.json get /ai/models Returns the full model catalog, the curated picker lists (Kai agent, Kai Code cloud, Kai Code OpenCode, transcription), and the per-runtime default model ids. Internal fields and markup metadata are not exposed; customer-facing cost figures are pre-computed. # Ask a question about the project's connected source repositories Source: https://docs.gleap.io/api-reference/code/ask-a-question-about-the-projects-connected-source-repositories https://api.gleap.io/api-docs.json post /code/ask Forwards the question to the code analyzer, which clones all repositories connected to this project, investigates them, and returns a user-facing answer (logic, behavior, click paths). The analyzer's system prompt enforces that no code, identifiers or secrets are included in answers. With no repositories connected the endpoint returns 200 with a canned no-repositories answer; it fails with 409 when the AI usage limit is reached. # Add a company member Source: https://docs.gleap.io/api-reference/company/add-a-company-member https://api.gleap.io/api-docs.json post /companies/{companyId}/members Link a contact to this company. `migrateTickets` opts into re-stamping the contact's existing conversations onto this company — off by default, since the stamp records which company a past conversation was had with. # Count companies Source: https://docs.gleap.io/api-reference/company/count-companies https://api.gleap.io/api-docs.json get /companies/count Number of companies matching the same `search` and `conditions` the list route accepts. Drives the live match count in the pipeline bulk-add filter. # Create or update a company Source: https://docs.gleap.io/api-reference/company/create-or-update-a-company https://api.gleap.io/api-docs.json put /companies/{companyId} Create or update a company by its external `companyId` (upsert). Only `name`, `plan`, `domain`, `value`, `sla`, `tags`, `address` and `customData` are accepted; any other field is ignored. `tags` REPLACES the stored list (an empty array clears it), while `address` and `customData` are merged into the existing values rather than replaced. `customData` accepts up to 100 primitive values, `tags` up to 50. Setting a non-empty `name` here marks it authoritative, so names sent by the SDK will no longer overwrite it. # Delete a company Source: https://docs.gleap.io/api-reference/company/delete-a-company https://api.gleap.io/api-docs.json delete /companies/{companyId} Delete a company by its external `companyId`. Contacts keep their `companyId` link and conversations keep their historical company stamp, so an SDK that still sends this `companyId` will lazily re-create the company on the next identify. # Get a company Source: https://docs.gleap.io/api-reference/company/get-a-company https://api.gleap.io/api-docs.json get /companies/{companyId} Get one company by its external `companyId`, the identifier your app sends via the SDK, not the Gleap `_id`. # Get company conversations Source: https://docs.gleap.io/api-reference/company/get-company-conversations https://api.gleap.io/api-docs.json get /companies/{companyId}/tickets List conversations stamped with this company at creation time, newest activity first. Paginated via `skip` (default 0) and `limit` (default 25, maximum 100). Conversations a contact had before being linked to the company are not included unless they were migrated. # Get company members Source: https://docs.gleap.io/api-reference/company/get-company-members https://api.gleap.io/api-docs.json get /companies/{companyId}/members List the contacts linked to a company, most recently active first. Paginated via `skip` (default 0) and `limit` (default 50, maximum 200). Each row contains only `_id`, `name`, `email`, `userId`, `avatar` and `lastActivity`. # List companies Source: https://docs.gleap.io/api-reference/company/list-companies https://api.gleap.io/api-docs.json get /companies List a project's companies, most recently seen first. Paginated via `skip` (default 0) and `limit` (default 50, maximum 200); `search` filters by a case-insensitive substring match on the company name. Returns a summary of each company (`companyId`, `name`, `plan`, `value`, `domain`, `lastSeenAt`, `createdAt`); use GET /companies/{companyId} for the full record. # Remove a company member Source: https://docs.gleap.io/api-reference/company/remove-a-company-member https://api.gleap.io/api-docs.json delete /companies/{companyId}/members/{sessionId} Unlink a contact from this company. Existing conversations keep their original company stamp. # Search companies Source: https://docs.gleap.io/api-reference/company/search-companies https://api.gleap.io/api-docs.json get /companies/search Free-text company search for the dashboard's global search, backed by OpenSearch. Matches an exact `companyId` or `domain`, then the company name (whole words, prefix, and a fuzzy fallback), ranked by relevance and capped at 25 hits. Use GET /companies for paginated browsing and filtering. Declared before GET /companies/{companyId} on purpose — tsoa registers routes in declaration order, so the reverse would make `/companies/search` resolve as a company whose id is literally "search". # Clear all contact memory entries Source: https://docs.gleap.io/api-reference/contactmemory/clear-all-contact-memory-entries https://api.gleap.io/api-docs.json delete /sessions/{sessionId}/memory Clear all memory entries for a contact. # Create or update a contact memory entry Source: https://docs.gleap.io/api-reference/contactmemory/create-or-update-a-contact-memory-entry https://api.gleap.io/api-docs.json post /sessions/{sessionId}/memory Create or upsert a memory entry by name. Returns `{ ok: true, entries: }`; invalid input returns 400 and an unknown session 404. Staff writes work even when the project's contact-memory feature is disabled. # Delete a contact memory entry Source: https://docs.gleap.io/api-reference/contactmemory/delete-a-contact-memory-entry https://api.gleap.io/api-docs.json delete /sessions/{sessionId}/memory/{entryName} Delete one memory entry by name. # Get one contact memory entry Source: https://docs.gleap.io/api-reference/contactmemory/get-one-contact-memory-entry https://api.gleap.io/api-docs.json get /sessions/{sessionId}/memory/{entryName} Get the full content of a single memory entry. # List contact memory entries Source: https://docs.gleap.io/api-reference/contactmemory/list-contact-memory-entries https://api.gleap.io/api-docs.json get /sessions/{sessionId}/memory List memory entries (no content) for a contact session. # Update a contact memory entry Source: https://docs.gleap.io/api-reference/contactmemory/update-a-contact-memory-entry https://api.gleap.io/api-docs.json put /sessions/{sessionId}/memory/{entryName} Create or replace the memory entry with this name; the entry is upserted, so a PUT to a name that does not exist yet creates it. This is a full replace, not a patch: omitting `description` clears the stored description. Returns `{ ok: true, entries: }`; invalid input returns 400 and an unknown session 404. Staff writes work even when the project's contact-memory feature is disabled. # Create a new custom component. Source: https://docs.gleap.io/api-reference/custom-components/create-a-new-custom-component https://api.gleap.io/api-docs.json post /custom-components Create a new custom AI message component. The template is sanitized server-side; unsafe markup is rejected with 400. # Delete a custom component. Source: https://docs.gleap.io/api-reference/custom-components/delete-a-custom-component https://api.gleap.io/api-docs.json delete /custom-components/{customComponentId} Delete a custom component. # Find all custom components. Source: https://docs.gleap.io/api-reference/custom-components/find-all-custom-components https://api.gleap.io/api-docs.json get /custom-components Find all custom components of a project. # Find one custom component. Source: https://docs.gleap.io/api-reference/custom-components/find-one-custom-component https://api.gleap.io/api-docs.json get /custom-components/{customComponentId} Find one custom component by ID. # Update a custom component. Source: https://docs.gleap.io/api-reference/custom-components/update-a-custom-component https://api.gleap.io/api-docs.json put /custom-components/{customComponentId} Update a custom component. The template is sanitized server-side; unsafe markup is rejected with 400. # Create a new banner Source: https://docs.gleap.io/api-reference/engagement-banner/create-a-new-banner https://api.gleap.io/api-docs.json post /engagement/banners Create a new engagement banner. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete a banner Source: https://docs.gleap.io/api-reference/engagement-banner/delete-a-banner https://api.gleap.io/api-docs.json delete /engagement/banners/{bannerId} Delete an engagement banner # Get a banner Source: https://docs.gleap.io/api-reference/engagement-banner/get-a-banner https://api.gleap.io/api-docs.json get /engagement/banners/{bannerId} Get an engagement banner # Get all banners Source: https://docs.gleap.io/api-reference/engagement-banner/get-all-banners https://api.gleap.io/api-docs.json get /engagement/banners Get the engagement banners of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Update a banner Source: https://docs.gleap.io/api-reference/engagement-banner/update-a-banner https://api.gleap.io/api-docs.json put /engagement/banners/{bannerId} Update an engagement banner. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new chat message Source: https://docs.gleap.io/api-reference/engagement-chat-message/create-a-new-chat-message https://api.gleap.io/api-docs.json post /engagement/chat-messages Create a new engagement chat message. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete a chat message Source: https://docs.gleap.io/api-reference/engagement-chat-message/delete-a-chat-message https://api.gleap.io/api-docs.json delete /engagement/chat-messages/{chatMessageId} Delete an engagement chat message # Get a chat message Source: https://docs.gleap.io/api-reference/engagement-chat-message/get-a-chat-message https://api.gleap.io/api-docs.json get /engagement/chat-messages/{chatMessageId} Get an engagement chat message # Get all chat messages Source: https://docs.gleap.io/api-reference/engagement-chat-message/get-all-chat-messages https://api.gleap.io/api-docs.json get /engagement/chat-messages Get the engagement chat messages of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Update a chat message Source: https://docs.gleap.io/api-reference/engagement-chat-message/update-a-chat-message https://api.gleap.io/api-docs.json put /engagement/chat-messages/{chatMessageId} Update an engagement chat message. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new checklist Source: https://docs.gleap.io/api-reference/engagement-checklist/create-a-new-checklist https://api.gleap.io/api-docs.json post /engagement/checklists Create a new engagement checklist. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete a checklist Source: https://docs.gleap.io/api-reference/engagement-checklist/delete-a-checklist https://api.gleap.io/api-docs.json delete /engagement/checklists/{checklistId} Delete an engagement checklist # Get a checklist Source: https://docs.gleap.io/api-reference/engagement-checklist/get-a-checklist https://api.gleap.io/api-docs.json get /engagement/checklists/{checklistId} Get an engagement checklist # Get all checklists Source: https://docs.gleap.io/api-reference/engagement-checklist/get-all-checklists https://api.gleap.io/api-docs.json get /engagement/checklists Get the engagement checklists of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Update a checklist Source: https://docs.gleap.io/api-reference/engagement-checklist/update-a-checklist https://api.gleap.io/api-docs.json put /engagement/checklists/{checklistId} Update an engagement checklist. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new cobrowse product tour Source: https://docs.gleap.io/api-reference/engagement-cobrowse/create-a-new-cobrowse-product-tour https://api.gleap.io/api-docs.json post /engagement/cobrowse Create a new engagement cobrowse product tour. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. `config.type` is set server-side as well. # Delete a cobrowse product tour Source: https://docs.gleap.io/api-reference/engagement-cobrowse/delete-a-cobrowse-product-tour https://api.gleap.io/api-docs.json delete /engagement/cobrowse/{cobrowseProductTourId} Delete an engagement cobrowse product tour # Get a cobrowse product tour Source: https://docs.gleap.io/api-reference/engagement-cobrowse/get-a-cobrowse-product-tour https://api.gleap.io/api-docs.json get /engagement/cobrowse/{cobrowseProductTourId} Get an engagement cobrowse product tour # Get all cobrowse product tours Source: https://docs.gleap.io/api-reference/engagement-cobrowse/get-all-cobrowse-product-tours https://api.gleap.io/api-docs.json get /engagement/cobrowse Get the engagement cobrowse product tours of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Update a cobrowse product tour Source: https://docs.gleap.io/api-reference/engagement-cobrowse/update-a-cobrowse-product-tour https://api.gleap.io/api-docs.json put /engagement/cobrowse/{cobrowseProductTourId} Update an engagement cobrowse product tour. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Check whether the visual editor will work on a URL Source: https://docs.gleap.io/api-reference/engagement-editor/check-whether-the-visual-editor-will-work-on-a-url https://api.gleap.io/api-docs.json post /engagement/editor/precheck Server-side precheck for the tooltip / product-tour editor. Fetches the given URL (SSRF-guarded) and reports blockers (COOP, CSP frame-src, login/cross-origin redirect, invalid URL) so the dashboard can give the user actionable feedback instead of opening a blank editor. # Create a new email Source: https://docs.gleap.io/api-reference/engagement-email/create-a-new-email https://api.gleap.io/api-docs.json post /engagement/emails Create a new engagement email. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete an email Source: https://docs.gleap.io/api-reference/engagement-email/delete-an-email https://api.gleap.io/api-docs.json delete /engagement/emails/{engagementEmailId} Permanently delete an engagement email, including its delivery records. This cannot be undone. # Get all emails Source: https://docs.gleap.io/api-reference/engagement-email/get-all-emails https://api.gleap.io/api-docs.json get /engagement/emails Get the engagement emails of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Get an email Source: https://docs.gleap.io/api-reference/engagement-email/get-an-email https://api.gleap.io/api-docs.json get /engagement/emails/{engagementEmailId} Get an engagement email # Send email preview Source: https://docs.gleap.io/api-reference/engagement-email/send-email-preview https://api.gleap.io/api-docs.json post /engagement/emails/{engagementEmailId}/send-email-preview Send email preview # Update an email Source: https://docs.gleap.io/api-reference/engagement-email/update-an-email https://api.gleap.io/api-docs.json put /engagement/emails/{engagementEmailId} Update an engagement email. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new modal Source: https://docs.gleap.io/api-reference/engagement-modal/create-a-new-modal https://api.gleap.io/api-docs.json post /engagement/modals Create a new engagement modal. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete a modal Source: https://docs.gleap.io/api-reference/engagement-modal/delete-a-modal https://api.gleap.io/api-docs.json delete /engagement/modals/{modalId} Delete an engagement modal # Get a modal Source: https://docs.gleap.io/api-reference/engagement-modal/get-a-modal https://api.gleap.io/api-docs.json get /engagement/modals/{modalId} Get an engagement modal # Get all modals Source: https://docs.gleap.io/api-reference/engagement-modal/get-all-modals https://api.gleap.io/api-docs.json get /engagement/modals Get the engagement modals of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Update a modal Source: https://docs.gleap.io/api-reference/engagement-modal/update-a-modal https://api.gleap.io/api-docs.json put /engagement/modals/{modalId} Update an engagement modal. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new engagement news article Source: https://docs.gleap.io/api-reference/engagement-news/create-a-new-engagement-news-article https://api.gleap.io/api-docs.json post /engagement/news Create a news article for a project. `subject` is required, either as `{ localized: { en: "..." } }` or as a bare per-language map `{ en: "..." }` (canonicalized server-side; same for `message` and `markdownMessage`). `sender` defaults to the authenticated user and `trigger` defaults to `sessionStarted`/`firstoccured` when omitted. Instead of `message` you may send `markdownMessage` (localized markdown), which is converted to rich text server-side. `searchContent` is computed server-side and ignored if supplied. Creating a `CHANGELOG` news item with `status: "live"` immediately sends changelog notification emails to subscribers. # Delete a news article. Source: https://docs.gleap.io/api-reference/engagement-news/delete-a-news-article https://api.gleap.io/api-docs.json delete /engagement/news/{newsId} Delete an engagement news article # Get all engagement news articles Source: https://docs.gleap.io/api-reference/engagement-news/get-all-engagement-news-articles https://api.gleap.io/api-docs.json get /engagement/news Get the engagement news articles of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. Pass `withoutChangelogs=true` (exact lowercase string) to exclude changelog entries (news items with subType `CHANGELOG`); any other value is ignored. # Get an engagement news article Source: https://docs.gleap.io/api-reference/engagement-news/get-an-engagement-news-article https://api.gleap.io/api-docs.json get /engagement/news/{newsId} Get a news article by id. # Update a news article. Source: https://docs.gleap.io/api-reference/engagement-news/update-a-news-article https://api.gleap.io/api-docs.json put /engagement/news/{newsId} Update an engagement news article. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new product tour Source: https://docs.gleap.io/api-reference/engagement-product-tour/create-a-new-product-tour https://api.gleap.io/api-docs.json post /engagement/product-tours Create a new engagement product tour. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. `config.type` is set server-side as well. # Delete a product tour Source: https://docs.gleap.io/api-reference/engagement-product-tour/delete-a-product-tour https://api.gleap.io/api-docs.json delete /engagement/product-tours/{productTourId} Delete an engagement product tour # Get a product tour Source: https://docs.gleap.io/api-reference/engagement-product-tour/get-a-product-tour https://api.gleap.io/api-docs.json get /engagement/product-tours/{productTourId} Get an engagement product tour # Get all product tours Source: https://docs.gleap.io/api-reference/engagement-product-tour/get-all-product-tours https://api.gleap.io/api-docs.json get /engagement/product-tours Get the engagement product tours of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Update a product tour Source: https://docs.gleap.io/api-reference/engagement-product-tour/update-a-product-tour https://api.gleap.io/api-docs.json put /engagement/product-tours/{productTourId} Update an engagement product tour. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new push notification Source: https://docs.gleap.io/api-reference/engagement-push-notification/create-a-new-push-notification https://api.gleap.io/api-docs.json post /engagement/push-notifications Create a new engagement push notification. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete a push notification Source: https://docs.gleap.io/api-reference/engagement-push-notification/delete-a-push-notification https://api.gleap.io/api-docs.json delete /engagement/push-notifications/{pushNotificationId} Delete an engagement push notification # Get a push notification Source: https://docs.gleap.io/api-reference/engagement-push-notification/get-a-push-notification https://api.gleap.io/api-docs.json get /engagement/push-notifications/{pushNotificationId} Get an engagement push notification # Get all push notifications Source: https://docs.gleap.io/api-reference/engagement-push-notification/get-all-push-notifications https://api.gleap.io/api-docs.json get /engagement/push-notifications Get the engagement push notifications of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Update a push notification Source: https://docs.gleap.io/api-reference/engagement-push-notification/update-a-push-notification https://api.gleap.io/api-docs.json put /engagement/push-notifications/{pushNotificationId} Update an engagement push notification. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new survey Source: https://docs.gleap.io/api-reference/engagement-survey/create-a-new-survey https://api.gleap.io/api-docs.json post /engagement/surveys Create a new engagement survey. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete a survey Source: https://docs.gleap.io/api-reference/engagement-survey/delete-a-survey https://api.gleap.io/api-docs.json delete /engagement/surveys/{surveyId} Permanently delete an engagement survey. This also deletes the survey's form definition and its delivery records. Already-collected responses are kept, but exporting them afterwards will no longer resolve question labels. This cannot be undone. # Export survey responses Source: https://docs.gleap.io/api-reference/engagement-survey/export-survey-responses https://api.gleap.io/api-docs.json get /engagement/surveys/{surveyId}/responses/export Export all responses of a survey as a downloadable file. CSV by default (`Content-Type: text/csv`, sent as an attachment named after the survey). Query parameters: `format=json` returns the same data as JSON instead; `label=keys` uses internal field names as column headers instead of the localized question titles. # Get a survey Source: https://docs.gleap.io/api-reference/engagement-survey/get-a-survey https://api.gleap.io/api-docs.json get /engagement/surveys/{surveyId} Get an engagement survey # Get all survey responses Source: https://docs.gleap.io/api-reference/engagement-survey/get-all-survey-responses https://api.gleap.io/api-docs.json get /engagement/surveys/{surveyId}/responses Get the responses of a survey, unread first, then newest first. Supports `skip`, `limit` (defaults to 1000 when omitted; supplied values above 100 are clamped to 100) and field filters via query parameters. # Get all surveys Source: https://docs.gleap.io/api-reference/engagement-survey/get-all-surveys https://api.gleap.io/api-docs.json get /engagement/surveys Get the engagement surveys of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Get survey response samples Source: https://docs.gleap.io/api-reference/engagement-survey/get-survey-response-samples https://api.gleap.io/api-docs.json get /engagement/surveys/{surveyId}/responses/samples Get a random sample of up to 10,000 responses for a survey, for client-side aggregation. Returns `{ samples, sampleSize, count }` where `count` is the total number of matching responses and `sampleSize` is the 10,000 sampling ceiling. Each sample is trimmed to `createdAt`, `formData`, `shareToken` and a minimal `session` (`_id`, `name`, `email`). # Mark all survey responses as read Source: https://docs.gleap.io/api-reference/engagement-survey/mark-all-survey-responses-as-read https://api.gleap.io/api-docs.json put /engagement/surveys/{surveyId}/responses/read Mark all engagement survey responses as read # Summarize survey responses Source: https://docs.gleap.io/api-reference/engagement-survey/summarize-survey-responses https://api.gleap.io/api-docs.json get /engagement/surveys/{surveyId}/responses/summarize Generate an AI summary of a survey's responses. Uses up to the 999 newest responses, truncated to fit a 30,000-token budget, so very large surveys are summarized from a recent subset. The generated summary is also stored on the survey as `aiSummary`. Consumes AI credits; returns `{ summary }` and fails with 409 when generation fails. # Update a survey Source: https://docs.gleap.io/api-reference/engagement-survey/update-a-survey https://api.gleap.io/api-docs.json put /engagement/surveys/{surveyId} Update an engagement survey. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new tooltip Source: https://docs.gleap.io/api-reference/engagement-tooltip/create-a-new-tooltip https://api.gleap.io/api-docs.json post /engagement/tooltips Create a new engagement tooltip. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete a tooltip Source: https://docs.gleap.io/api-reference/engagement-tooltip/delete-a-tooltip https://api.gleap.io/api-docs.json delete /engagement/tooltips/{tooltipId} Delete an engagement tooltip # Get a tooltip Source: https://docs.gleap.io/api-reference/engagement-tooltip/get-a-tooltip https://api.gleap.io/api-docs.json get /engagement/tooltips/{tooltipId} Get an engagement tooltip # Get all tooltips Source: https://docs.gleap.io/api-reference/engagement-tooltip/get-all-tooltips https://api.gleap.io/api-docs.json get /engagement/tooltips Get the engagement tooltips of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Update a tooltip Source: https://docs.gleap.io/api-reference/engagement-tooltip/update-a-tooltip https://api.gleap.io/api-docs.json put /engagement/tooltips/{tooltipId} Update an engagement tooltip. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Create a new whatsapp message Source: https://docs.gleap.io/api-reference/engagement-whatsapp-messages/create-a-new-whatsapp-message https://api.gleap.io/api-docs.json post /engagement/whatsapp-messages Create a new engagement WhatsApp message. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Delete a whatsapp message Source: https://docs.gleap.io/api-reference/engagement-whatsapp-messages/delete-a-whatsapp-message https://api.gleap.io/api-docs.json delete /engagement/whatsapp-messages/{whatsappMessageId} Permanently delete an engagement WhatsApp message, including its delivery records. This cannot be undone. # Get a whatsapp message Source: https://docs.gleap.io/api-reference/engagement-whatsapp-messages/get-a-whatsapp-message https://api.gleap.io/api-docs.json get /engagement/whatsapp-messages/{whatsappMessageId} Get an engagement whatsapp message # Get all WhatsApp messages Source: https://docs.gleap.io/api-reference/engagement-whatsapp-messages/get-all-whatsapp-messages https://api.gleap.io/api-docs.json get /engagement/whatsapp-messages Get the engagement WhatsApp messages of a project, newest first. Supports filtering by any field via query parameters, plus `skip`, `limit` and `sort` (e.g. `sort=-createdAt`). `limit` defaults to 1000 when omitted; when supplied, values above 100 are clamped to 100. Filtering by `project` or `organisation` is rejected. # Send a whatsapp template message Source: https://docs.gleap.io/api-reference/engagement-whatsapp-messages/send-a-whatsapp-template-message https://api.gleap.io/api-docs.json post /engagement/whatsapp-messages/send-template Send a WhatsApp template message to a phone number with optional custom variable values. The customValues keys must match the templateVariable names from your variable mapping. In addition, the reserved keys `header_image`, `header_video`, `header_document` and `header_media` override the template's configured header media URL and do not need a variable-mapping entry. When a custom value is provided for a variable, it takes priority over the mapped field resolution and fallback value. Missing required fields or an unknown channel return 400; a send rejected by WhatsApp returns 409 with `{ success: false, message }`. # Update a whatsapp message Source: https://docs.gleap.io/api-reference/engagement-whatsapp-messages/update-a-whatsapp-message https://api.gleap.io/api-docs.json put /engagement/whatsapp-messages/{whatsappMessageId} Update an engagement WhatsApp message. Any pending (not yet sent) deliveries for this engagement are discarded and re-queued from the updated document. While an engagement is live, its audience, targeting and scheduling fields cannot be changed (for `fixed` frequency engagements neither can its content); pause it first or the request fails with 409. Setting `status` to `live` starts delivery. `type`, `project`, `organisation` and `createdBy` are set server-side and ignored if supplied. # Clone engagement Source: https://docs.gleap.io/api-reference/engagement/clone-engagement https://api.gleap.io/api-docs.json post /engagements/{engagementId}/clone Clone an engagement. The copy is always created as a draft named "Copy of "; `name` and `status` sent in the body are ignored. Any other body fields override the cloned values. # Export engagement recipients Source: https://docs.gleap.io/api-reference/engagement/export-engagement-recipients https://api.gleap.io/api-docs.json get /engagements/{engagementId}/recipients/export Export the recipients of a single engagement as CSV (`Content-Type: text/csv`, sent as an attachment named after the engagement). Accepts the same `filter` query as the recipients list, so a filtered view (e.g. only recipients who opened) exports exactly what is shown. # Find engagement recipients Source: https://docs.gleap.io/api-reference/engagement/find-engagement-recipients https://api.gleap.io/api-docs.json get /engagements/{engagementId}/recipients Get the recipients of a single engagement. Returns `{ data, total }`. # Get engagement activities Source: https://docs.gleap.io/api-reference/engagement/get-engagement-activities https://api.gleap.io/api-docs.json get /engagements/{engagementId}/activities Get the activities recorded for a single engagement, paginated via `skip`/`limit`. # Get engagement activities count Source: https://docs.gleap.io/api-reference/engagement/get-engagement-activities-count https://api.gleap.io/api-docs.json get /engagements/{engagementId}/activities/count Get the number of activities recorded for a single engagement. Returns `{ count }`. # Get engagement fixed audience samples Source: https://docs.gleap.io/api-reference/engagement/get-engagement-fixed-audience-samples https://api.gleap.io/api-docs.json post /engagements/{engagementId}/fixed-audience-samples Estimate the fixed audience of an engagement. Send `targetAudience` and `conditions` in the body to preview a candidate audience without saving it. Returns `{ sample, count, limitReached, limit }`. On an internal error the endpoint still answers 200 with an empty sample and `count: 0`. # Get engagement statistics Source: https://docs.gleap.io/api-reference/engagement/get-engagement-statistics https://api.gleap.io/api-docs.json get /engagements/{engagementId}/statistics Get delivery and response statistics for a single engagement. Responds 404 for an unknown engagement. # Deliver a frontend tool execution result. Source: https://docs.gleap.io/api-reference/frontendtools/deliver-a-frontend-tool-execution-result https://api.gleap.io/api-docs.json post /frontend-tools/result Deliver the result of a frontend tool execution from the customer's app. Called by the Gleap SDK. Requires the project API key in the `api-token` header plus a valid widget session (`gleap-id`/`gleap-hash` headers); returns 401 otherwise and 403 if the calling domain is not an allowed widget domain. `result`/`error` payloads above 50,000 characters are rejected with 400; accepted payloads are truncated to 20,000 characters before being handed to the agent. (Gleap.registerAgentTool handler) back to the awaiting agent. # Create a new article Source: https://docs.gleap.io/api-reference/help-center-articles/create-a-new-article https://api.gleap.io/api-docs.json post /helpcenter/collections/{helpcenterCollectionId}/articles Create a new help center article in a collection. `title`, `description` and `content` may be sent either localized (`{ "en": ... }`) or as a bare value, which is stored under the help center's default language. `project`, `helpcenterCollection`, `docId`, `lexorank`, `plainContent` and `baseAudienceFilter` are assigned by the server and ignored if sent. The article is created unpublished (`isDraft: true`) unless `isDraft: false` is passed. `content` is TipTap JSON. Images are `image` nodes referencing a hosted image URL: `{ "type": "image", "attrs": { "src": "" } }`. To host images on the Gleap CDN, upload them first via `POST /v3/uploads` (or import from an existing URL via `POST /v3/uploads/from-url`) and use the returned `fileUrl` as the `src`. # Create an article version checkpoint Source: https://docs.gleap.io/api-reference/help-center-articles/create-an-article-version-checkpoint https://api.gleap.io/api-docs.json post /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/versions Capture a manual version checkpoint of the article's current state # Delete an article Source: https://docs.gleap.io/api-reference/help-center-articles/delete-an-article https://api.gleap.io/api-docs.json delete /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId} Delete a help center article # Discard an article draft Source: https://docs.gleap.io/api-reference/help-center-articles/discard-an-article-draft https://api.gleap.io/api-docs.json delete /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/draft Discard the staged draft of an article (the live article is untouched) # Get all articles Source: https://docs.gleap.io/api-reference/help-center-articles/get-all-articles https://api.gleap.io/api-docs.json get /helpcenter/collections/{helpcenterCollectionId}/articles Get every article in a help center collection, published and unpublished, sorted by `lexorank`. This endpoint is not paginated. # Get an article Source: https://docs.gleap.io/api-reference/help-center-articles/get-an-article https://api.gleap.io/api-docs.json get /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId} Get a help center article by id. Pass format=html or format=markdown to additionally include the article content converted to that format (as a localized contentHtml / contentMarkdown field) next to the stored editor JSON. Omit the parameter to return the article unchanged. # Get an article draft Source: https://docs.gleap.io/api-reference/help-center-articles/get-an-article-draft https://api.gleap.io/api-docs.json get /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/draft Get the staged (unpublished) draft of a help center article, or null # Get an article version Source: https://docs.gleap.io/api-reference/help-center-articles/get-an-article-version https://api.gleap.io/api-docs.json get /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/versions/{versionId} Get a single version snapshot of a help center article, including its content # List article versions Source: https://docs.gleap.io/api-reference/help-center-articles/list-article-versions https://api.gleap.io/api-docs.json get /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/versions List the retained version snapshots of a help center article (newest first) # Move an article Source: https://docs.gleap.io/api-reference/help-center-articles/move-an-article https://api.gleap.io/api-docs.json put /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/move Move a help center article to a different collection # Publish an article draft Source: https://docs.gleap.io/api-reference/help-center-articles/publish-an-article-draft https://api.gleap.io/api-docs.json post /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/draft/publish Publish a staged draft to the live article (promote). Pass force=true to override the warning when the live article changed since the draft started. # Reorder articles Source: https://docs.gleap.io/api-reference/help-center-articles/reorder-articles https://api.gleap.io/api-docs.json put /helpcenter/collections/{helpcenterCollectionId}/articles/order Set the order of the articles in a collection. Send every article id in the order they should appear; the server rewrites all of the collection's ranks so the order is exact and stable. Articles left out of the list keep their relative order and follow the listed ones. Returns the collection's articles in their new order. # Restore an article version Source: https://docs.gleap.io/api-reference/help-center-articles/restore-an-article-version https://api.gleap.io/api-docs.json post /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/versions/{versionId}/restore Restore a help center article to a previous version (the current state is snapshotted first, so the restore itself can be undone) # Save an article draft Source: https://docs.gleap.io/api-reference/help-center-articles/save-an-article-draft https://api.gleap.io/api-docs.json put /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId}/draft Create or update the staged draft of an article. The live article is never modified by this call; use the draft publish endpoint to promote it. # Update an article Source: https://docs.gleap.io/api-reference/help-center-articles/update-an-article https://api.gleap.io/api-docs.json put /helpcenter/collections/{helpcenterCollectionId}/articles/{helpcenterArticleId} Update a help center article. `content` is TipTap JSON; images are `image` nodes referencing a hosted image URL (`{ "type": "image", "attrs": { "src": "" } }`) — upload files via `POST /v3/uploads` first and use the returned `fileUrl` as the `src`. # Create a new collection Source: https://docs.gleap.io/api-reference/help-center-collections/create-a-new-collection https://api.gleap.io/api-docs.json post /helpcenter/collections Create a new help center collection. `project`, `docId` and `lexorank` are assigned by the server and ignored if sent. When `parent` is set, `baseAudienceFilter` is inherited from the parent collection (any value sent is overwritten) and an unknown `parent` returns 404. # Delete a collection Source: https://docs.gleap.io/api-reference/help-center-collections/delete-a-collection https://api.gleap.io/api-docs.json delete /helpcenter/collections/{helpcenterCollectionId} Delete a help center collection. The collection must be empty: the request is rejected with 409 while it still contains articles. Subcollections are not deleted; move or delete them first. Returns `{ success: true }`. # Get a collection Source: https://docs.gleap.io/api-reference/help-center-collections/get-a-collection https://api.gleap.io/api-docs.json get /helpcenter/collections/{helpcenterCollectionId} Get a help center collection by id # Get all collections Source: https://docs.gleap.io/api-reference/help-center-collections/get-all-collections https://api.gleap.io/api-docs.json get /helpcenter/collections Get help center collections. Returns only top-level collections by default; pass `parentId=` to list the direct children of a collection, or `parentId=all` to list every collection. Results are sorted by `lexorank` and each entry includes `articlesCount` and `subCollectionsCount`. Note: this endpoint returns the dashboard view of a collection; `project` and `externalId` are omitted. Use GET /helpcenter/collections/all for full documents. # Get all collections with subcollections Source: https://docs.gleap.io/api-reference/help-center-collections/get-all-collections-with-subcollections https://api.gleap.io/api-docs.json get /helpcenter/collections/all Get all help center collections (subcollections included) # Get article stats Source: https://docs.gleap.io/api-reference/help-center-collections/get-article-stats https://api.gleap.io/api-docs.json get /helpcenter/collections/stats Get live/draft article counts across the whole help center # Publish or unpublish a collection's articles Source: https://docs.gleap.io/api-reference/help-center-collections/publish-or-unpublish-a-collections-articles https://api.gleap.io/api-docs.json put /helpcenter/collections/{helpcenterCollectionId}/toggle-publish Publish or unpublish every article in a help center collection. Set `unpublished` to `true` to unpublish or `false` to publish; the change is applied recursively to all articles in this collection and in all of its subcollections. The collection document itself is not modified. Returns `{ success: true }`. # Reorder collections Source: https://docs.gleap.io/api-reference/help-center-collections/reorder-collections https://api.gleap.io/api-docs.json put /helpcenter/collections/order Set the order of the collections on one level of the tree. Send every collection id in the order they should appear, plus the `parentId` whose children are being ordered (omit it for the top level). The server rewrites all of that level's ranks so the order is exact and stable; siblings left out keep their relative order and follow the listed ones. Returns the level's collections in their new order. # Update a collection Source: https://docs.gleap.io/api-reference/help-center-collections/update-a-collection https://api.gleap.io/api-docs.json put /helpcenter/collections/{helpcenterCollectionId} Update a help center collection. Changing `targetAudience`, `baseAudienceFilter` or `extendedAudienceFilter` also re-applies the resulting audience filter to every article in this collection and, recursively, to all subcollections and their articles. # Create a new redirect. Source: https://docs.gleap.io/api-reference/help-center-redirects/create-a-new-redirect https://api.gleap.io/api-docs.json post /helpcenter-redirect Create a new redirect. # Delete a redirect Source: https://docs.gleap.io/api-reference/help-center-redirects/delete-a-redirect https://api.gleap.io/api-docs.json delete /helpcenter-redirect/{redirectId} Delete a redirect. # Find all redirects. Source: https://docs.gleap.io/api-reference/help-center-redirects/find-all-redirects https://api.gleap.io/api-docs.json get /helpcenter-redirect Find all redirects of a project. # Update a redirect. Source: https://docs.gleap.io/api-reference/help-center-redirects/update-a-redirect https://api.gleap.io/api-docs.json put /helpcenter-redirect/{redirectId} Update a redirect. # Answer help center question Source: https://docs.gleap.io/api-reference/help-center/answer-help-center-question https://api.gleap.io/api-docs.json get /shared/helpcenter/answer Answer a visitor question with AI, grounded in the project's help center content. Pass the question in the `question` query parameter (required) and optionally `lang`. Returns the generated answer under `answer`. Same authentication headers as the search endpoint. # Get help center sources Source: https://docs.gleap.io/api-reference/help-center/get-help-center-sources https://api.gleap.io/api-docs.json get /shared/helpcenter/sources Find the help center sources (articles and indexed URLs) most relevant to a search term, as used for AI answers. `searchTerm` is required (the request fails without it). Each source is returned with `id`, `title`, `url` and a short `extract`. Same authentication headers as the search endpoint; `lang` optional. # Search help center articles Source: https://docs.gleap.io/api-reference/help-center/search-help-center-articles https://api.gleap.io/api-docs.json get /shared/helpcenter/search Full-text search the published articles of a help center. Returns at most 30 hits, filtered to the requested language and to the articles the current visitor session is allowed to see. Hits are returned under `data.hits`, alongside the help center's `project` configuration and any `domainRedirect`. Authentication: the `api-token` header must carry the help center domain (e.g. `acme-app.gleap.help` or your custom domain); a `password` header is required for password-protected help centers; optional `gleap-id`/`gleap-hash` headers resolve the visitor session for audience filtering. Query parameters: `searchTerm` (required), `lang` (defaults to `en`, falling back to the help center's first configured language), `collectionId` (restrict results to one collection). # Accept or decline an invitation Source: https://docs.gleap.io/api-reference/invitation/accept-or-decline-an-invitation https://api.gleap.io/api-docs.json put /invitations/{invitationId} Accept or decline an invitation addressed to the authenticated user. On accept the user is added to the organisation or project with the invitation's role. The invitation is consumed (deleted) either way. Fails with 409 if the invitation was issued to a different email, the user has not confirmed their email, or the target organisation has no seats left. # Delete an invitation Source: https://docs.gleap.io/api-reference/invitation/delete-an-invitation https://api.gleap.io/api-docs.json delete /invitations/{invitationId} Delete an invitation. # Get all invitations for a project Source: https://docs.gleap.io/api-reference/invitation/get-all-invitations-for-a-project https://api.gleap.io/api-docs.json get /invitations/projects Get all invitations for a project. The project is taken from the required `project` header. # Get all invitations for a user Source: https://docs.gleap.io/api-reference/invitation/get-all-invitations-for-a-user https://api.gleap.io/api-docs.json get /invitations Get all invitations for a user. # Get all invitations for an organisation Source: https://docs.gleap.io/api-reference/invitation/get-all-invitations-for-an-organisation https://api.gleap.io/api-docs.json get /invitations/organisations/{organisationId} Get all invitations for an organisation. # Invite people to a project Source: https://docs.gleap.io/api-reference/invitation/invite-people-to-a-project https://api.gleap.io/api-docs.json post /invitations/projects Invite one or more people (body: `{ "emails": [...] }`) to the project given in the required `project` header. Each invitation is created with the `user` role and an invitation email is sent. Returns the subset of submitted email addresses that were SKIPPED because they already belong to the project or its organisation; an empty array means every address was invited. Fails with a plan error if the organisation cannot seat that many additional teammates. # Invite people to an organisation Source: https://docs.gleap.io/api-reference/invitation/invite-people-to-an-organisation https://api.gleap.io/api-docs.json post /invitations/organisations/{organisationId} Invite one or more people (body: `{ "emails": [...] }`) to an organisation. Each invitation is created with the `user` role and an invitation email is sent. Returns the subset of submitted email addresses that were SKIPPED because they are already members; an empty array means every address was invited. # Update an invitation's role Source: https://docs.gleap.io/api-reference/invitation/update-an-invitations-role https://api.gleap.io/api-docs.json put /invitations/{invitationId}/role Change the role an invitation will grant when accepted. Invitations are always created with the `user` role, so this is the way to grant a different role before acceptance. Requires invitation permissions on the project given in the `project` header. # Find similar tickets Source: https://docs.gleap.io/api-reference/knowledge/find-similar-tickets https://api.gleap.io/api-docs.json post /knowledge/similar-tickets Search for similar tickets using vector similarity search. Returns tickets with a similarity score of at least 0.3. # Get content tags in use Source: https://docs.gleap.io/api-reference/knowledge/get-content-tags-in-use https://api.gleap.io/api-docs.json get /knowledge/content-tags Get the distinct set of content tags actually in use across the project's knowledge content (snippets/FAQ/files/youtube answers, help-center articles, and web-crawler pages). Read-only — does not read or modify the project's tag registry. # Search knowledge documents Source: https://docs.gleap.io/api-reference/knowledge/search-knowledge-documents https://api.gleap.io/api-docs.json post /knowledge/search Search through knowledge base documents using vector search and reranking. Returns matching documents from help-center articles, FAQs/snippets, websites, news, YouTube videos, and code knowledge. `limit` caps the number of returned documents; retrieval returns at most 10 documents regardless of a higher limit. # Create a new message template. Source: https://docs.gleap.io/api-reference/message-templates/create-a-new-message-template https://api.gleap.io/api-docs.json post /message-templates Create a new message template. # Delete a message template Source: https://docs.gleap.io/api-reference/message-templates/delete-a-message-template https://api.gleap.io/api-docs.json delete /message-templates/{messageTemplateId} Delete a message template. # Find a message template. Source: https://docs.gleap.io/api-reference/message-templates/find-a-message-template https://api.gleap.io/api-docs.json get /message-templates/{messageTemplateId} Find a single message template of a project by its ID. # Find all message templates. Source: https://docs.gleap.io/api-reference/message-templates/find-all-message-templates https://api.gleap.io/api-docs.json get /message-templates Find the message templates of a project that are visible to the calling agent (public templates plus templates shared with them), ordered by `lexorank`. # List all message template tags. Source: https://docs.gleap.io/api-reference/message-templates/list-all-message-template-tags https://api.gleap.io/api-docs.json get /message-templates/tags List the distinct tags used across the project's message templates, sorted alphabetically. # Update a message template. Source: https://docs.gleap.io/api-reference/message-templates/update-a-message-template https://api.gleap.io/api-docs.json put /message-templates/{messageTemplateId} Update a message template. # Accept or decline an AI FAQ suggestion Source: https://docs.gleap.io/api-reference/messages/accept-or-decline-an-ai-faq-suggestion https://api.gleap.io/api-docs.json post /messages/{messageId}/faq Resolves an AI-generated FAQ suggestion message. With `accept: true` the suggested question/answer pair is added to the knowledge base; with `accept: false` it is discarded. Either way the suggestion message is deleted. # Create a new message Source: https://docs.gleap.io/api-reference/messages/create-a-new-message https://api.gleap.io/api-docs.json post /messages Create a new message in a ticket. Required field: `ticket` (ticket ID). Optional fields: `comment` (rich text as TipTap doc JSON, or a plain string) or `markdownComment` (Markdown, converted server-side; takes precedence over `comment`), `type` (defaults to `TEXT`, or `NOTE` when `isNote` is true), `isNote` (creates an internal note), `attachments` (array of `{ name, url, type }`), `channel`, `replyTo` (message ID to quote), `data`, and `actions`. Other schema properties are accepted for backwards compatibility but are ignored on create; messages are always attributed to the authenticated user. # Create a thread reply Source: https://docs.gleap.io/api-reference/messages/create-a-thread-reply https://api.gleap.io/api-docs.json post /messages/{messageId}/thread Reply inside a message's thread. Thread replies are INTERNAL — they never reach the customer, never fire webhooks/integrations/SLA, and never move the ticket's latest message. # Delete a message Source: https://docs.gleap.io/api-reference/messages/delete-a-message https://api.gleap.io/api-docs.json delete /messages/{messageId} Delete a message from a ticket. # Find messages by query Source: https://docs.gleap.io/api-reference/messages/find-messages-by-query https://api.gleap.io/api-docs.json get /messages Get messages by query with support for filtering and pagination. **Filtering:** - Filter by ticket: `ticket=507f1f77bcf86cd799439011`. Any identifier `GET /tickets/{ticketId}` accepts works here too — the human-facing ticket number shown in the dashboard (`ticket=143790`), the 24-char ObjectId, or the shareToken. - Filter by type: `type=TEXT` or `type=TEXT,NOTE` (comma-separated values match any; bracket syntax such as `type[$in]=...` is NOT supported) - Filter by bot messages: `bot=true` or `bot=false` - Filter by date range: `createdAt>=2024-01-01&createdAt<=2024-12-31` **Ordering:** Messages are always returned oldest-first (ascending `createdAt`); the sort order is not configurable. **Pagination:** - Cursor mode (recommended): pass `paginated=true` to receive `{ items, hasMore, nextBefore }`; pass `before=` (the previous `nextBefore`) to fetch the next older page. `skip` is ignored in this mode; `limit` defaults to 30 and is clamped to 1-100. - Legacy mode (no `paginated`): returns a flat array; `limit` defaults to 1000 and values above 100 are clamped to 100; `skip` is applied. **Exporting a full conversation:** Filter by `ticket` rather than by `bot`. `bot=true` selects messages exchanged with the AI bot, so on a conversation that was handed over to a human it omits the agent's replies — `ticket={ticketId}` returns the complete transcript. Thread replies are not part of the main feed either; fetch them per message with `GET /messages/{messageId}/thread`. Which conversations still exist is governed by retention — AI-only (`type=BOT`) conversations are deleted about 33 days after they are created, see GET /tickets. **Ticket history:** Since August 2026 this endpoint returns conversation messages only. Audit entries — `FEEDBACK_UPDATED` (status, assignee, team, priority, type, tag, title changes, …) and workflow/system entries — are no longer part of the response; filtering by those types returns an empty result. Fetch them from `GET /tickets/{ticketId}/history`, which returns them in the same message-compatible shape. **Translation:** - `language=es` returns messages translated into the given language. Requires the project setting 'translate customer messages'; only conversation messages (`TEXT`, `USER_TEXT`, `NOTE`, `BOT`, `BOT_REPLY`, `SHARED_COMMENT`) are translated, and messages already in the target language are returned unchanged. # Get thread messages Source: https://docs.gleap.io/api-reference/messages/get-thread-messages https://api.gleap.io/api-docs.json get /messages/{messageId}/thread Get the messages of a thread, oldest first. # Search messages Source: https://docs.gleap.io/api-reference/messages/search-messages https://api.gleap.io/api-docs.json get /messages/search Search messages by query. # Set a message reaction Source: https://docs.gleap.io/api-reference/messages/set-a-message-reaction https://api.gleap.io/api-docs.json put /messages/{messageId}/reactions Add or remove an emoji reaction on a message. Reactions are INTERNAL — never visible to end customers, never fire webhooks/SLA/unread, never move the ticket's latest message. The update reaches open dashboards via the ordinary comment.updated broadcast. # Update a message Source: https://docs.gleap.io/api-reference/messages/update-a-message https://api.gleap.io/api-docs.json put /messages/{messageId} Edit an existing message. Only `data` (the message content, e.g. `data.content` as TipTap JSON) and `attachments` are persisted; all other schema properties are ignored, and `data` is replaced wholesale (an omitted `data` clears the content). Agents may only edit their own messages, sent through the widget or email channel, that the contact has not read yet and that are less than 2 minutes old; own internal notes can be edited at any time. # Get an entry Source: https://docs.gleap.io/api-reference/pipeline-entries/get-an-entry https://api.gleap.io/api-docs.json get /pipeline-entries/{entryId} Get one entry together with its pipeline, as `{ entry, pipeline }`. Also powers the ticket sidebar's "Pipeline" panel and the board's entry route (…/entries/:entryId). 404 when the entry isn't in this project. MUST stay the LAST @Get of this controller: tsoa registers routes in declaration order, and `{entryId}` declared above `for-record` would swallow it (entryId = "for-record"). # Move an entry Source: https://docs.gleap.io/api-reference/pipeline-entries/move-an-entry https://api.gleap.io/api-docs.json put /pipeline-entries/{entryId}/move Move an entry to another stage of its pipeline. `laneId` is the target stage's id from the pipeline's `lanes`; an id that does not exist on the entry's pipeline is ignored rather than errored. Omit `lexorank` to place the entry at the end of the target stage — it is the board position rank and only needs to be sent for an exact drag-and-drop position. Moving to a new stage runs the pipeline automations configured for that stage. # Remove an entry Source: https://docs.gleap.io/api-reference/pipeline-entries/remove-an-entry https://api.gleap.io/api-docs.json delete /pipeline-entries/{entryId} Remove an entry from its pipeline. Only the pipeline membership is deleted — the underlying company or contact is untouched. # Set an entry's due date Source: https://docs.gleap.io/api-reference/pipeline-entries/set-an-entrys-due-date https://api.gleap.io/api-docs.json put /pipeline-entries/{entryId}/due-date Set or clear the entry's due date — when the next step on it is due. Send an ISO date string to set it, or `null` to clear it. The board shows it on the card and turns the card red once the date has passed; the table can sort by it. # Update entry values Source: https://docs.gleap.io/api-reference/pipeline-entries/update-entry-values https://api.gleap.io/api-docs.json put /pipeline-entries/{entryId}/values Update an entry's field values. Keys are the pipeline's field `fieldId`s (see GET /pipelines/{pipelineId}/properties). Sent keys are merged into the existing values — fields you do not send are left untouched — and sending `null` clears a field. Values must be primitives (string, number, boolean); anything else is dropped. # Update record values through an entry Source: https://docs.gleap.io/api-reference/pipeline-entries/update-record-values-through-an-entry https://api.gleap.io/api-docs.json put /pipeline-entries/{entryId}/record-values Update the company or contact behind an entry through the pipeline's RECORD fields. Keys are the `fieldId`s of fields with `source: 'RECORD'` (see GET /pipelines/{pipelineId}/properties); the value is written to the record itself, so every pipeline showing that attribute — and the record's own page — reflect it. `null` clears the attribute. A key that is not a writable record field of this pipeline is rejected with 400. # Add a record to a pipeline Source: https://docs.gleap.io/api-reference/pipelines/add-a-record-to-a-pipeline https://api.gleap.io/api-docs.json post /pipelines/{pipelineId}/entries Add a company or contact to a pipeline. `recordId` is the Gleap id of the record — a company's `_id` (see GET /companies) or a contact's `id`, matching the pipeline's `recordType`. `laneId` picks the stage and defaults to the pipeline's first stage; `values` sets initial field values keyed by `fieldId` (see GET /pipelines/{pipelineId}/properties). A record sits on a pipeline at most once: adding one that is already present returns the existing entry unchanged instead of creating a duplicate. Pipeline automations configured for "record added" run on a genuine add. # Get a pipeline Source: https://docs.gleap.io/api-reference/pipelines/get-a-pipeline https://api.gleap.io/api-docs.json get /pipelines/{pipelineId} Get one pipeline by its id, including its stages (`lanes`) and column configuration. A pipeline holds records of exactly one type: companies or contacts (`recordType`). # List entries of a stage Source: https://docs.gleap.io/api-reference/pipelines/list-entries-of-a-stage https://api.gleap.io/api-docs.json get /pipelines/{pipelineId}/entries List the entries of one stage, ordered by their board position. `laneId` is the stage's id from the pipeline's `lanes`. Paginated via `skip` (default 0) and `limit` (default 50, maximum 200). # List pipeline fields Source: https://docs.gleap.io/api-reference/pipelines/list-pipeline-fields https://api.gleap.io/api-docs.json get /pipelines/{pipelineId}/properties The fields of one pipeline, in column order. A field's `source` says where its value lives: `ENTRY` fields are stored on the entry — their `fieldId`s are the keys entry `values` accept — while `RECORD` fields read (and write through to) an attribute of the company or contact and arrive on entries as `recordValues`. `type`, `unit` and `calculation` say how to render a value and what the stage footers total. # List pipelines Source: https://docs.gleap.io/api-reference/pipelines/list-pipelines https://api.gleap.io/api-docs.json get /pipelines List the pipelines visible to the authenticated user, most recently updated first. A pipeline is visible when it is public or explicitly shared with the user — an API service account only sees public pipelines and those it was added to. Each pipeline carries its stages in `lanes` (`id`, `title`, `color`, `order`, `archived`); pass a lane's `id` as `laneId` when adding or moving entries. # Get all users for a project Source: https://docs.gleap.io/api-reference/project/get-all-users-for-a-project https://api.gleap.io/api-docs.json get /projects/users Get everyone who can access this project: direct project members plus all members of its organisation. Each entry carries `type` (`project` or `organisation`) and `role`. Service accounts are excluded. # Remove a member from a project Source: https://docs.gleap.io/api-reference/project/remove-a-member-from-a-project https://api.gleap.io/api-docs.json delete /projects/users/{userId} Remove a member from the project given in the required `project` header. The user is also removed from every team in that project. The user account itself is not deleted. Returns 404 if the user is not a direct member of the project (organisation-level members cannot be removed here). # Update a project member's role Source: https://docs.gleap.io/api-reference/project/update-a-project-members-role https://api.gleap.io/api-docs.json put /projects/users/{userId} Change a member's role within the project given in the required `project` header. Only the project creator or an admin of the project/organisation may do this, and you cannot change your own role (403). Returns `true`. # Conversation counts for a record Source: https://docs.gleap.io/api-reference/records/conversation-counts-for-a-record https://api.gleap.io/api-docs.json get /records/{recordType}/{recordId}/counts Open and total conversation counts for a record, so a tab can show a real number instead of the size of whatever page happens to be loaded. # Conversations waiting on us Source: https://docs.gleap.io/api-reference/records/conversations-waiting-on-us https://api.gleap.io/api-docs.json get /records/{recordType}/{recordId}/waiting The record's open conversations, longest-waiting first. Team-wide by definition — unlike the per-agent visit stamp this replaced. # Record summary Source: https://docs.gleap.io/api-reference/records/record-summary https://api.gleap.io/api-docs.json get /records/{recordType}/{recordId}/summary The written brief for a record. Never precomputed: this route is the only thing that ever generates one, so a record nobody opens costs nothing. Returns `status` — `disabled` (feature off), `not-enough-data`, or `ok` with the summary, optionally flagged `stale` when the cooldown is holding a summary the record has since moved past. # Refresh a record summary Source: https://docs.gleap.io/api-reference/records/refresh-a-record-summary https://api.gleap.io/api-docs.json post /records/{recordType}/{recordId}/summary/refresh Regenerates the summary, bypassing the staleness cooldown. Rate limited to once a minute per record — the cooldown is what bounds automatic spend, so the manual path needs its own floor or it becomes the way around it. # What is coming up on a record Source: https://docs.gleap.io/api-reference/records/what-is-coming-up-on-a-record https://api.gleap.io/api-docs.json get /records/{recordType}/{recordId}/upcoming Everything on the record with a date in the future — snoozed conversations waking, pipeline due dates and date-typed attributes, merged and sorted. # Create conversation Source: https://docs.gleap.io/api-reference/s2s-contacts/create-conversation https://api.gleap.io/api-docs.json post /s2s/contacts/{userId}/conversations Open a conversation for a contact, authored as the contact. Pass workflowId to start a workflow, or agentId to engage an AI agent. The contact is created on the fly if it does not exist yet. # Delete contact Source: https://docs.gleap.io/api-reference/s2s-contacts/delete-contact https://api.gleap.io/api-docs.json delete /s2s/contacts/{userId} Delete a contact and their conversations (the platform's standard contact deletion — same behaviour as the admin API). # Get contact Source: https://docs.gleap.io/api-reference/s2s-contacts/get-contact https://api.gleap.io/api-docs.json get /s2s/contacts/{userId} Fetch a contact including its unread conversation count. # List contact conversations Source: https://docs.gleap.io/api-reference/s2s-contacts/list-contact-conversations https://api.gleap.io/api-docs.json get /s2s/contacts/{userId}/conversations List the contact's conversations, most recent activity first. Bot-only conversations without human interaction are hidden — exactly the widget's conversation list. # Track contact events Source: https://docs.gleap.io/api-reference/s2s-contacts/track-contact-events https://api.gleap.io/api-docs.json post /s2s/contacts/{userId}/events Track events for a contact (drives outbound messaging and workflows). # Upsert contact Source: https://docs.gleap.io/api-reference/s2s-contacts/upsert-contact https://api.gleap.io/api-docs.json put /s2s/contacts/{userId} Create or update a contact. Returns the full contact including its unread conversation count. # Answer workflow step Source: https://docs.gleap.io/api-reference/s2s-conversations/answer-workflow-step https://api.gleap.io/api-docs.json post /s2s/conversations/{conversationId}/workflow/answer Answer the pending workflow step (text, selection, rating, attachments) or request a human with botAction "humanHandoff". # Close conversation Source: https://docs.gleap.io/api-reference/s2s-conversations/close-conversation https://api.gleap.io/api-docs.json post /s2s/conversations/{conversationId}/close Close the conversation for the contact. Further contact messages are rejected with `conversation_closed` until it is reopened. # Get conversation Source: https://docs.gleap.io/api-reference/s2s-conversations/get-conversation https://api.gleap.io/api-docs.json get /s2s/conversations/{conversationId} Fetch a conversation. Attributes are filtered to customer-visible ones. # Get pending workflow step Source: https://docs.gleap.io/api-reference/s2s-conversations/get-pending-workflow-step https://api.gleap.io/api-docs.json get /s2s/conversations/{conversationId}/workflow The workflow step currently waiting for the contact, if any. # List messages Source: https://docs.gleap.io/api-reference/s2s-conversations/list-messages https://api.gleap.io/api-docs.json get /s2s/conversations/{conversationId}/messages Read the conversation's messages, oldest first, cursor-paginated (max 100 per page). Pass `after` = the last message id you have. Reading messages does NOT mark the conversation read — use the explicit read receipt. # Mark conversation read Source: https://docs.gleap.io/api-reference/s2s-conversations/mark-conversation-read https://api.gleap.io/api-docs.json post /s2s/conversations/{conversationId}/read Mark the conversation read for the contact (explicit read receipt). Clears the contact's unread state for this conversation. # Rate conversation Source: https://docs.gleap.io/api-reference/s2s-conversations/rate-conversation https://api.gleap.io/api-docs.json post /s2s/conversations/{conversationId}/rating Rate the conversation (CSAT), integer 0–10. # Reopen conversation Source: https://docs.gleap.io/api-reference/s2s-conversations/reopen-conversation https://api.gleap.io/api-docs.json post /s2s/conversations/{conversationId}/reopen Reopen a closed conversation. # Run workflow Source: https://docs.gleap.io/api-reference/s2s-conversations/run-workflow https://api.gleap.io/api-docs.json post /s2s/conversations/{conversationId}/workflow/{workflowId}/run Run a specific workflow on this conversation (replaces any active one). # Send message Source: https://docs.gleap.io/api-reference/s2s-conversations/send-message https://api.gleap.io/api-docs.json post /s2s/conversations/{conversationId}/messages Send a message into the conversation, authored as the contact. # Set conversation events Source: https://docs.gleap.io/api-reference/s2s-conversations/set-conversation-events /openapi/s2s-openapi.json put /s2s/conversations/{conversationId}/events Attach an event log snapshot to the conversation — the same events `Gleap.trackEvent()` buffers in the SDK flow and attaches when a conversation is created. Scoped to this conversation only (not the contact), so events from other sessions never mix in. Shown to agents in the conversation's "Logs" panel. Each call replaces the previous snapshot (max 500 events, 2 MB). Not delivered via webhooks or the stream. For contact-level events that drive outbound rules, use `POST /contacts/{userId}/events` instead. # Set network logs Source: https://docs.gleap.io/api-reference/s2s-conversations/set-network-logs https://api.gleap.io/api-docs.json put /s2s/conversations/{conversationId}/network-logs Attach a network log snapshot to the conversation — the same logs `Gleap.logNetwork()` collects in the SDK flow. Shown to agents in the conversation's "Logs" panel. Each call replaces the previous snapshot (max 100 requests, 2 MB). Not delivered via webhooks or the stream. # Typing indicator Source: https://docs.gleap.io/api-reference/s2s-conversations/typing-indicator https://api.gleap.io/api-docs.json post /s2s/conversations/{conversationId}/typing Signal that the contact is typing (or stopped typing). Debounce on your side; send only while a conversation is on screen. # Update conversation Source: https://docs.gleap.io/api-reference/s2s-conversations/update-conversation https://api.gleap.io/api-docs.json patch /s2s/conversations/{conversationId} Update conversation title and/or attributes (merge semantics). # Get message Source: https://docs.gleap.io/api-reference/s2s-messages/get-message https://api.gleap.io/api-docs.json get /s2s/messages/{messageId} Fetch a single message. # Rate message Source: https://docs.gleap.io/api-reference/s2s-messages/rate-message https://api.gleap.io/api-docs.json post /s2s/messages/{messageId}/rating Rate a message (thumbs up / down) — typically an AI answer. # Authenticate stream user Source: https://docs.gleap.io/api-reference/s2s-stream/authenticate-stream-user https://api.gleap.io/api-docs.json post /s2s/stream/user-auth User authentication (Pusher signin) — REQUIRED for server-side takeover termination to reach your connection. Configure it as the client's userAuthentication endpoint. # Authorize channel subscription Source: https://docs.gleap.io/api-reference/s2s-stream/authorize-channel-subscription https://api.gleap.io/api-docs.json post /s2s/stream/auth Channel authorization — point your Pusher client's channel auth here with your server key as the Authorization header. A new consumerId takes over from the previous consumer (its connection is terminated). # Get stream config Source: https://docs.gleap.io/api-reference/s2s-stream/get-stream-config https://api.gleap.io/api-docs.json get /s2s/stream/config Connection parameters. Read these at startup instead of hardcoding — if the realtime infrastructure moves, your client follows automatically. # Upload a file Source: https://docs.gleap.io/api-reference/s2s-uploads/upload-a-file /openapi/s2s-openapi.json post /s2s/uploads Multipart upload (field `file`, max 25 MB). Returned URLs are signed and expire — attach them to a message promptly and never persist them. Idempotency-Key is not supported on multipart uploads (re-uploading is safe: every upload mints a fresh URL). # Upload a voice note Source: https://docs.gleap.io/api-reference/s2s-uploads/upload-a-voice-note /openapi/s2s-openapi.json post /s2s/uploads/audio Multipart upload (field `file`, max 25 MB). Transcoded to MP3 server-side. # Create webhook Source: https://docs.gleap.io/api-reference/s2s-webhooks/create-webhook https://api.gleap.io/api-docs.json post /s2s/webhooks Register a webhook endpoint. The signing secret is returned exactly once. # Delete webhook Source: https://docs.gleap.io/api-reference/s2s-webhooks/delete-webhook https://api.gleap.io/api-docs.json delete /s2s/webhooks/{webhookId} Delete a webhook endpoint. # List webhooks Source: https://docs.gleap.io/api-reference/s2s-webhooks/list-webhooks https://api.gleap.io/api-docs.json get /s2s/webhooks List webhook endpoints (secrets masked). # List workflows Source: https://docs.gleap.io/api-reference/s2s-workflows/list-workflows https://api.gleap.io/api-docs.json get /s2s/workflows List the project's live workflows. # Create a new session Source: https://docs.gleap.io/api-reference/session/create-a-new-session https://api.gleap.io/api-docs.json post /sessions Create a session (contact) in the project from the `project` header. When `userId` is supplied this is an upsert: an existing contact with that userId is updated and returned instead of a new one being created (one session per project + userId). Without `userId` a new guest/email session is always created. # Delete a session Source: https://docs.gleap.io/api-reference/session/delete-a-session https://api.gleap.io/api-docs.json delete /sessions/{sessionId} Delete a session by id. This also permanently deletes every ticket attached to the session, a hard delete that emits no ticket events or webhooks. # Export sessions Source: https://docs.gleap.io/api-reference/session/export-sessions https://api.gleap.io/api-docs.json get /sessions/export Export the project's contacts as a CSV file download (`Content-Type: text/csv`, filename `users.csv`). Not filterable; query parameters are ignored. Only contacts with an email address are included, capped at 75,000 rows, with a fixed column set (userId, name, email, phone, companyName, companyId, lang, plan, value, sla, deviceType, platform, tags, sessions, blocked, unsubscribed, firstActivity, lastActivity, createdAt, customData). # Get a session Source: https://docs.gleap.io/api-reference/session/get-a-session https://api.gleap.io/api-docs.json get /sessions/{sessionId} Get a session by id. # Get a session by user id Source: https://docs.gleap.io/api-reference/session/get-a-session-by-user-id https://api.gleap.io/api-docs.json get /sessions/by-user-id/{userId} Get a session by the contact's external user id (`Session.userId`, the id your app passes to the SDK identify call), not the Mongo `_id`. Responds 404 when no contact with that userId exists. # Get all sessions Source: https://docs.gleap.io/api-reference/session/get-all-sessions https://api.gleap.io/api-docs.json get /sessions List sessions (contacts) of the project. Paginated: `limit` defaults to 50 and is capped at 100 per page, and paging cannot go past the first 10,000 results. Optional query parameters: `type` (`users` = has userId, `guests` = no userId, `unsubscribed`, or `organisations`; the latter returns aggregated organisations instead of sessions), `companyId` (only sessions of this company), `withFeedback` (only sessions with at least one ticket), `contactViewId` (returns the sessions matching a saved contact view; 404 when the view does not exist), plus `skip` and `sort`. # Get session activities Source: https://docs.gleap.io/api-reference/session/get-session-activities https://api.gleap.io/api-docs.json get /sessions/{sessionId}/activities Get the tickets ("activities") of a session, newest activity first. If the session has an email address, tickets from other sessions in the project sharing that email are included as well and are flagged with `isFromDuplicateSession: true`. Query parameters: `limit` (default 50), `skip` (default 0), `startDate`/`endDate` (ISO dates filtering on ticket `createdAt`; only applied when both are present). # Get session Chargebee info Source: https://docs.gleap.io/api-reference/session/get-session-chargebee-info https://api.gleap.io/api-docs.json get /sessions/{sessionId}/chargebee Get Chargebee information for a session. Returns `{ customer, subscriptions, invoices }` when the Chargebee integration is configured and a customer matches the session; otherwise an empty object. # Get session checklists Source: https://docs.gleap.io/api-reference/session/get-session-checklists https://api.gleap.io/api-docs.json get /sessions/{sessionId}/checklists Get the non-draft checklists of a session, most recently updated first. Each entry contains only `completedSteps` and the parent outbound's name and step titles/ids. Query parameter `limit`: default 3, maximum 10. # Get session events Source: https://docs.gleap.io/api-reference/session/get-session-events https://api.gleap.io/api-docs.json get /sessions/{sessionId}/events Get the streamed events of a session, newest first. Events emitted by outbounds are relabelled to " submitted". Query parameter `limit`: number of events to return, default 5, maximum 300. # Get session identity history Source: https://docs.gleap.io/api-reference/session/get-session-identity-history https://api.gleap.io/api-docs.json get /sessions/{sessionId}/identity-history Get the identity-change history for a session: recorded mutations of email / name / userId on this contact record, capped at the 100 most recent entries and returned as `{ history: [...] }`. Stripped from default session responses (see session.model.ts toJSON), so this is the only path that returns it. # Get session LemonSqueezy info Source: https://docs.gleap.io/api-reference/session/get-session-lemonsqueezy-info https://api.gleap.io/api-docs.json get /sessions/{sessionId}/lemonsqueezy Get LemonSqueezy information for a session. Returns `{ customer, subscriptions, invoices }` when the LemonSqueezy integration is configured and a customer matches the session; otherwise an empty object. # Get session Shopify info Source: https://docs.gleap.io/api-reference/session/get-session-shopify-info https://api.gleap.io/api-docs.json get /sessions/{sessionId}/shopify Get Shopify information for a session. Returns `{ customer, orders, shopDomain }`; `customer` may be null for guest checkouts; returns an empty object when the integration is not configured or no customer matches. # Get session Stripe info Source: https://docs.gleap.io/api-reference/session/get-session-stripe-info https://api.gleap.io/api-docs.json get /sessions/{sessionId}/stripe Get Stripe information for a session. Returns `{ customer, charges, subscriptions }` when the Stripe integration is configured and a customer matches the session; otherwise an empty object. # Import sessions Source: https://docs.gleap.io/api-reference/session/import-sessions https://api.gleap.io/api-docs.json post /sessions/importer Bulk-import sessions (contacts). The body must be `{ "sessions": [...] }`. Every entry is matched against an existing contact before anything is created — by `userId` when the row carries one, otherwise by `email` — so importing the same list twice updates those contacts instead of duplicating them. Returns the ids of the imported sessions. At most `MAX_IMPORT_SESSIONS_PER_REQUEST` rows per call: a request has to finish well inside the edge's 60s window, and a larger list belongs in a sequence of these calls. Oversized bodies are rejected rather than truncated. # Import sessions from HubSpot Source: https://docs.gleap.io/api-reference/session/import-sessions-from-hubspot https://api.gleap.io/api-docs.json post /sessions/importer/hubspot Import sessions from HubSpot. # Import sessions from intercom Source: https://docs.gleap.io/api-reference/session/import-sessions-from-intercom https://api.gleap.io/api-docs.json post /sessions/importer/intercom Import sessions from intercom. # Import sessions from Zendesk Source: https://docs.gleap.io/api-reference/session/import-sessions-from-zendesk https://api.gleap.io/api-docs.json post /sessions/importer/zendesk Import sessions (contacts) from Zendesk. # Pre-warm sessions cache for the active project Source: https://docs.gleap.io/api-reference/session/pre-warm-sessions-cache-for-the-active-project https://api.gleap.io/api-docs.json post /sessions/warmup Pre-warm OpenSearch shards + Redis list cache for the active project. Fire-and-forget: returns {ok:true} immediately while the warmup runs in the background. Triggered from the frontend right before a session query is likely (sidebar hover, global search modal mount, RecipientPicker mount, periodic refresh while on the Sessions page) so the user doesn't pay the cold-shard penalty on first interaction. # Reset session checklist Source: https://docs.gleap.io/api-reference/session/reset-session-checklist https://api.gleap.io/api-docs.json post /sessions/{sessionId}/checklists/{checklistId}/reset Reset a checklist for a session — clears all completed steps and sets it back to active. # Resubscribe a session Source: https://docs.gleap.io/api-reference/session/resubscribe-a-session https://api.gleap.io/api-docs.json put /sessions/{sessionId}/resubscribe Resubscribe a session. # Search for sessions Source: https://docs.gleap.io/api-reference/session/search-for-sessions https://api.gleap.io/api-docs.json get /sessions/search Autocomplete search over the project's sessions. Returns at most 50 matches, each containing only `id`, `email`, `userId`, `name`, `companyId`, `companyName` and `phone`. Query parameters: `searchTerm` (required; terms shorter than 3 characters return an empty array) and `fieldExists` (optional; only return sessions where that field is set; allowed values: email, userId, phone, companyId, name, companyName, tags, plan, value, sla, lang, avatar, facebookId, instagramId, instagramUsername, telegramChatId, telegramUsername; other values are ignored). Optional scoping: `contactViewId` limits results to the sessions matching that saved contact view (its conditions apply exactly as in the list route; `type`/`withFeedback` are ignored alongside it); without it, `type` (users | guests | unsubscribed), `withFeedback=true` and `companyId` narrow the search like the list route. `fullContact=true` returns full session documents (without the kv blobs) instead of the 7 autocomplete fields. # Unsubscribe sessions Source: https://docs.gleap.io/api-reference/session/unsubscribe-sessions https://api.gleap.io/api-docs.json post /sessions/unsubscribe Unsubscribe contacts by email and/or userId. Fire-and-forget: the response is always `{ "success": true }` and does not reflect whether the contacts were found or updated. Every session in the project matching an entry's email OR userId is unsubscribed; entries with neither field are ignored. # Update a session Source: https://docs.gleap.io/api-reference/session/update-a-session https://api.gleap.io/api-docs.json put /sessions/{sessionId} Update a session (contact) in the project from the `project` header. The fields `userId`, `project`, `organisation`, `gleapId` and `gleapHash` are ignored if sent. Changing `tags` requires the tag permissions of the calling agent. Setting `companyId` automatically creates the company if it does not exist yet. # Get statisticsbar chart Source: https://docs.gleap.io/api-reference/statistics/get-statisticsbar-chart https://api.gleap.io/api-docs.json get /statistics/bar-chart Get bar chart data for various statistics # Get statisticsemail client bounces Source: https://docs.gleap.io/api-reference/statistics/get-statisticsemail-client-bounces https://api.gleap.io/api-docs.json get /statistics/email-client-bounces Get email client bounce statistics. Pass `outboundId` (query) to restrict the statistics to a single outbound campaign. # Get statisticsemail client usage Source: https://docs.gleap.io/api-reference/statistics/get-statisticsemail-client-usage https://api.gleap.io/api-docs.json get /statistics/email-client-usage Get email client usage statistics. Pass `outboundId` (query) to restrict the statistics to a single outbound campaign. # Get statisticsemail overview Source: https://docs.gleap.io/api-reference/statistics/get-statisticsemail-overview https://api.gleap.io/api-docs.json get /statistics/email-overview Get email overview statistics. Pass `outboundId` (query) to restrict the statistics to a single outbound campaign. # Get statisticsfacts Source: https://docs.gleap.io/api-reference/statistics/get-statisticsfacts https://api.gleap.io/api-docs.json get /statistics/facts Get fact data for various statistics # Get statisticsheatmap Source: https://docs.gleap.io/api-reference/statistics/get-statisticsheatmap https://api.gleap.io/api-docs.json get /statistics/heatmap Get heatmap data for activity patterns # Get statisticslists Source: https://docs.gleap.io/api-reference/statistics/get-statisticslists https://api.gleap.io/api-docs.json get /statistics/lists Get list data for various statistics # Get statisticslistsexport Source: https://docs.gleap.io/api-reference/statistics/get-statisticslistsexport https://api.gleap.io/api-docs.json get /statistics/lists/export Export list data as CSV. Returns a UTF-8 CSV file as an attachment (`Content-Disposition: attachment`), not JSON. # Get statisticsraw data Source: https://docs.gleap.io/api-reference/statistics/get-statisticsraw-data https://api.gleap.io/api-docs.json get /statistics/raw-data Get raw statistics data. Filterable fields: `actionType` (e.g. `HOME_MENU_CLICK`), `resourceType` (e.g. `WIDGET`), `actionUser`, `associatedEntity`, `description`, `first`, `rowId`, and the `data.*` fields (`data.type`, `data.tags`, `data.processingUser`, `data.ticketId`, …). Suffix a filter with `_gte`, `_lte`, `_gt`, `_lt`, `_ne`, `_in` or `_nin` for range/set operators. At most 10000 rows are returned; `skip`/`limit` are ignored. A filter on a field this table doesn't have is rejected with a 400 naming the field and listing the supported ones. Row timestamps are UTC; `timezone` does not apply here (it only affects bucketed endpoints). # Create a new team Source: https://docs.gleap.io/api-reference/team/create-a-new-team https://api.gleap.io/api-docs.json post /teams Create a new team and associate it with a project. # Delete a team Source: https://docs.gleap.io/api-reference/team/delete-a-team https://api.gleap.io/api-docs.json delete /teams/{teamId} Delete a team. # Get all teams Source: https://docs.gleap.io/api-reference/team/get-all-teams https://api.gleap.io/api-docs.json get /teams Get all teams associated with a project. # Reorder a team Source: https://docs.gleap.io/api-reference/team/reorder-a-team https://api.gleap.io/api-docs.json put /teams/{teamId}/order Update a team's ordering position in the inbox sidebar. # Update a team Source: https://docs.gleap.io/api-reference/team/update-a-team https://api.gleap.io/api-docs.json put /teams/{teamId} Update a team. # Archive a ticket Source: https://docs.gleap.io/api-reference/ticket/archive-a-ticket https://api.gleap.io/api-docs.json put /tickets/{ticketId}/archive Archive a ticket in a project. # Archive all tickets in a lane Source: https://docs.gleap.io/api-reference/ticket/archive-all-tickets-in-a-lane https://api.gleap.io/api-docs.json put /tickets/archive/all Archives every non-archived ticket of the given `type` and `status` (both required in the body). Pass the board's active `filter` (the same JSON string GET /tickets takes) to archive only the filtered subset — omit it to archive the whole lane. Processes at most 1000 tickets per call; repeat the call to drain larger lanes. Returns `true`. # Await customer reply on a ticket Source: https://docs.gleap.io/api-reference/ticket/await-customer-reply-on-a-ticket https://api.gleap.io/api-docs.json put /tickets/{ticketId}/await-customer-reply Park a ticket as "waiting on customer": set expectsReply and archive it. The customer's next reply automatically un-archives, clears the flag, and resumes any awaiting agent. # Bulk-reply to tickets Source: https://docs.gleap.io/api-reference/ticket/bulk-reply-to-tickets https://api.gleap.io/api-docs.json post /tickets/bulk/reply Send the same customer-visible reply to every ticket in the selection. Unlike bulk updates there is NO fast path — every reply runs the full createComment pipeline (channel/email delivery, notifications, SLA clearing, workflows, integrations). Selections up to 30 send inline; larger ones (up to 500) fan out as per-ticket scheduled replies firing ~60s later, delivered by the Bull worker with the reconcile-sweep backstop and cancellable per ticket until they fire. # Bulk-update tickets Source: https://docs.gleap.io/api-reference/ticket/bulk-update-tickets https://api.gleap.io/api-docs.json put /tickets/bulk Bulk close / assign / archive / snooze / team / priority. Selection is either an explicit id list or a lane query ("all matching", optionally limited to the first N in sort order). Small selections (<= 30) run the full per-ticket update cascade; larger ones run a fast updateMany that skips workflows, webhooks, integrations and per-ticket notifications. # Clear the composer draft message Source: https://docs.gleap.io/api-reference/ticket/clear-the-composer-draft-message https://api.gleap.io/api-docs.json delete /tickets/{ticketId}/draft-message Remove the composer draft message from a ticket. No-op when the ticket has no draft. # Close a ticket as spam (agent verdict) Source: https://docs.gleap.io/api-reference/ticket/close-a-ticket-as-spam-agent-verdict https://api.gleap.io/api-docs.json put /tickets/{ticketId}/close-as-spam CLOSE a ticket as spam (agent/MCP verdict): sets the done status, flags + archives it into the Spam review queue, and suppresses every customer-facing follow-up — no CSAT, no notifications, no knowledge extraction. Unlike the manual `PUT {ticketId}/spam` above it does NOT block the contact: agent verdicts stay recoverable (a genuine customer reply un-flags the ticket). Used by the Gleap MCP's close_ticket (asSpam) and the classic close_as_spam tool. # Create a new ticket Source: https://docs.gleap.io/api-reference/ticket/create-a-new-ticket https://api.gleap.io/api-docs.json post /tickets Create a new ticket in a project. Every field is optional. Common fields include: `title`, `description`, `type` (BUG, FEATURE_REQUEST, etc.), `status`, `priority` (LOW, MEDIUM, HIGH), `session` (contact/session ID if manually added), and `customData` (custom fields). Use `linkedTickets` to reference existing tickets. # Create a new ticket with an optional initial message Source: https://docs.gleap.io/api-reference/ticket/create-a-new-ticket-with-an-optional-initial-message https://api.gleap.io/api-docs.json post /tickets/compose Create a new ticket and optionally post an initial message in a single request. Provide either a session (contact ID) or email to associate the ticket with a contact. If an email is provided and no contact exists, one will be created automatically. # Create a tracker ticket Source: https://docs.gleap.io/api-reference/ticket/create-a-tracker-ticket https://api.gleap.io/api-docs.json post /tickets/tracker-tickets Create a tracker ticket in a project. When `customerEmail` is set, the customer is added as the first upvoter (`upvotes: [{ email, name }]`, `upvotesCount: 1`) and their session (source ticket's session, else resolved by email) becomes the ticket's creator `session` — used for feature requests where the originating customer should own the request like a portal-submitted one. # Delete a ticket Source: https://docs.gleap.io/api-reference/ticket/delete-a-ticket https://api.gleap.io/api-docs.json delete /tickets/{ticketId} Permanently deletes a ticket; this cannot be undone. Also deletes every ticket merged into it as a duplicate, along with all messages, scheduled replies, console/network logs and replay data, and removes the ticket from other tickets' linked lists. Fires the `TICKET_DELETED` webhook. Returns an empty body. # Export a single ticket for audit Source: https://docs.gleap.io/api-reference/ticket/export-a-single-ticket-for-audit https://api.gleap.io/api-docs.json get /tickets/{ticketId}/audit-export Returns an audit-focused CSV export of one ticket: one row per event in strict chronological order with the columns `timestamp, actor, actor_email, event_type, detail, content`. Covers messages, internal notes, status/assignee/priority/tag changes and automated/system actions; routing (team/assignee) is included in the `detail` text of the ticket-created and inbox-entered rows. Downloaded as `ticket__audit.csv` (text/csv). # Export tickets as CSV Source: https://docs.gleap.io/api-reference/ticket/export-tickets-as-csv https://api.gleap.io/api-docs.json get /tickets/csv-export Streams the project's tickets as a CSV download (`tickets.csv`, `text/csv`). Columns come from the ticket type's export fields; pass `type` (defaults to `BUG`) and optionally `projection[]` to pick specific fields. Supports `startDate`/`endDate` plus the usual ticket filters. For a JSON export use GET /tickets/export instead. Like GET /tickets/export, this includes archived tickets by default (`ignoreArchived` is accepted and ignored) and exports ticket records only, not their conversations. Retention limits which conversations still exist — see GET /tickets. # Export tickets as JSON Source: https://docs.gleap.io/api-reference/ticket/export-tickets-as-json https://api.gleap.io/api-docs.json get /tickets/export Returns the project's tickets as a JSON array, capped at 25,000 tickets. Supports the usual ticket filters. For larger exports or CSV output use GET /tickets/csv-export. Unlike GET /tickets, exports include archived tickets by default — there is no `ignoreArchived` to set (it is accepted and ignored). Narrow the export with `archived=true` / `archived=false` instead. This endpoint returns ticket records only, not their conversations: fetch each ticket's messages with GET /messages?ticket={ticketId}. Retention limits which conversations still exist — see GET /tickets. # Extended ticket search (contacts + tickets) Source: https://docs.gleap.io/api-reference/ticket/extended-ticket-search-contacts-+-tickets https://api.gleap.io/api-docs.json get /tickets/extendedsearch Searches contacts and tickets in parallel and returns two buckets: `sessionResults` (tickets belonging to matching contacts, with their latest comment) and `generalResults`. Each bucket is capped at 250 tickets. Query parameters: `searchTerm` (required), `type` (match mode: `STRICT` by default, or `BROAD`; note this is NOT the ticket type here), `ticketType` (optional ticket type filter; by default CRASH, SURVEY and BOT tickets are excluded), `ticketStatus` (optional status filter), `addSession` (set to `true` to include contact data). # Find duplicate feature requests Source: https://docs.gleap.io/api-reference/ticket/find-duplicate-feature-requests https://api.gleap.io/api-docs.json post /tickets/deduplicate Returns previously computed duplicate groups for the project's feature requests from a cache; `{ groups: [] }` when nothing is cached yet. Pass `?force=true` (or `{ "force": true }` in the body) to run a fresh AI scan; results are cached for 24 hours. The scan covers up to 2000 active feature requests; archived, hidden, spam, already-merged and DONE tickets are excluded. The `project` header is required. # Find tickets by session query Source: https://docs.gleap.io/api-reference/ticket/find-tickets-by-session-query https://api.gleap.io/api-docs.json get /tickets/by-session-query Resolves contacts (sessions) matching the given identifiers (at most 100) and returns their tickets as `{ tickets, count, totalCount }`. Archived, hidden, spam and merged-duplicate tickets are excluded and at most 500 tickets are returned. Pass at least one of `email`, `userId`, `phone` or `customData.TIN`. # Find tracker tickets Source: https://docs.gleap.io/api-reference/ticket/find-tracker-tickets https://api.gleap.io/api-docs.json get /tickets/tracker-tickets Find tracker tickets in a project. # Generate tracker ticket data with AI Source: https://docs.gleap.io/api-reference/ticket/generate-tracker-ticket-data-with-ai https://api.gleap.io/api-docs.json post /tickets/generate-data Uses AI to draft a tracker ticket from an existing ticket. Returns `{ title, description }`: a short title and a ~30-word summary written in the project's default summary language. Responds 404 when `sourceTicketId` does not resolve to a ticket. `type` (e.g. `FEATURE_REQUEST`) is used as prompt context. # Get a ticket Source: https://docs.gleap.io/api-reference/ticket/get-a-ticket https://api.gleap.io/api-docs.json get /tickets/{ticketId} Get a ticket in a project. # Get activity logs for a ticket Source: https://docs.gleap.io/api-reference/ticket/get-activity-logs-for-a-ticket https://api.gleap.io/api-docs.json get /tickets/{ticketId}/activity-logs Get activity logs for a ticket in a project. # Get all tickets Source: https://docs.gleap.io/api-reference/ticket/get-all-tickets https://api.gleap.io/api-docs.json get /tickets Get all tickets in a project with support for filtering, sorting, and pagination. **Filtering:** - Filter by type: `type=BUG` or `type=BUG,FEATURE_REQUEST` - Filter by status: `status=OPEN` - Filter by priority: `priority=HIGH` or `priority=HIGH,MEDIUM` - Filter by archived state: archived tickets are hidden by default; pass `ignoreArchived=true` to include them, or `ignoreArchived=true&archived=true` for archived tickets only - Filter by spam: `isSpam=false` - Filter the archive by archive date: `startDate` / `endDate` (ISO 8601) narrow the archive, spam and waiting-on-customer views to tickets archived within that range. Ignored on the non-archive views, where `archivedAt` is unset. **Sorting:** - Sort by creation date: `sort=-createdAt` (newest first) or `sort=createdAt` (oldest first) - Sort by priority: `sort=priority` (highest first: HIGH, MEDIUM, LOW) or `sort=-priority` (lowest first) - Sort by updated date: `sort=-updatedAt` - Default sort (no `sort` param): most recent activity first (`lastNotification` descending) - Archived, spam and waiting-on-customer views always sort by `archivedAt` descending; a `sort` param is ignored there **Pagination:** - Limit results: `limit=20` (default: 500, max: 500) - Skip results: `skip=0` (for pagination: `skip=(page-1)*limit`) **Retention — read this before building an export:** - `type=BOT` conversations (AI conversations that never reached a human) are closed and archived about 3 days after they are created, and permanently deleted 30 days after that. Roughly the last 33 days are available; older AI-only conversations no longer exist and cannot be exported or restored. - Every other ticket type is permanently deleted 365 days after it was archived, or after the project's custom archive window if one is configured. Unarchived tickets are never deleted by retention. - A conversation handed over to a human stops being `type=BOT` (it becomes `INQUIRY` or the type the handover assigns) and from then on follows the longer window above. - Ticket history entries have their own 180-day window — see GET /tickets/{ticketId}/history. # Get console logs for a ticket Source: https://docs.gleap.io/api-reference/ticket/get-console-logs-for-a-ticket https://api.gleap.io/api-docs.json get /tickets/{ticketId}/console-logs Get console logs for a ticket in a project. # Get network logs for a ticket Source: https://docs.gleap.io/api-reference/ticket/get-network-logs-for-a-ticket https://api.gleap.io/api-docs.json get /tickets/{ticketId}/network-logs Get network logs for a ticket in a project. # Get notification ticket Source: https://docs.gleap.io/api-reference/ticket/get-notification-ticket https://api.gleap.io/api-docs.json get /tickets/notification/{shareToken} Get notification ticket. The dashboard calls this for every websocket ticket event whose ticket isn't already loaded — it is a READ, gated on TICKET_FIND like GET /tickets. It previously required TICKET_EXPORT (copied from the export endpoints around it), which silently broke realtime inserts for any custom role that can view the inbox but not export. # Get the internal history of a ticket Source: https://docs.gleap.io/api-reference/ticket/get-the-internal-history-of-a-ticket https://api.gleap.io/api-docs.json get /tickets/{ticketId}/history Every internal history entry for a ticket — status, assignee, team, priority, type, tag, contact, due-date and title changes, plus workflow starts, agent handoffs and mirrored integration status updates. Returned oldest first in a comment-compatible shape so the conversation feed can splice them inline. Not paginated: `truncated` is true when the ticket has more entries than `limit` (default 1000, max 5000). Prior to August 2026 these entries were returned by `GET /messages` as `FEEDBACK_UPDATED` and system messages; this endpoint is now their only source. The shape is unchanged — a status change, for example, is `{ type: 'FEEDBACK_UPDATED', data: { type: 'STATUS', value: } }` with the acting user on `user`. Entries are retained for 180 days. # Get the session replay for a ticket Source: https://docs.gleap.io/api-reference/ticket/get-the-session-replay-for-a-ticket https://api.gleap.io/api-docs.json get /tickets/{ticketId}/replay Returns a self-contained HTML page that plays back the ticket's recorded session replay. Responds 404 when the ticket has no replay recording. # Get ticket counts per status Source: https://docs.gleap.io/api-reference/ticket/get-ticket-counts-per-status https://api.gleap.io/api-docs.json get /tickets/ticketscount Returns the number of tickets grouped by status, as `[{ "_id": "OPEN", "count": 12 }, ...]`. Counts always exclude archived, hidden, spam and merged-duplicate tickets. Other filters (e.g. `type`, `tags`, `processingUser`) are applied; a `status` filter is ignored because the result is already grouped by status. # Indicate user typing Source: https://docs.gleap.io/api-reference/ticket/indicate-user-typing https://api.gleap.io/api-docs.json post /tickets/{ticketId}/typing Indicate user is typing. # Indicate user viewing Source: https://docs.gleap.io/api-reference/ticket/indicate-user-viewing https://api.gleap.io/api-docs.json post /tickets/{ticketId}/viewing Indicate user is viewing. # Link a ticket to another ticket Source: https://docs.gleap.io/api-reference/ticket/link-a-ticket-to-another-ticket https://api.gleap.io/api-docs.json put /tickets/{ticketId}/link Creates a bidirectional link between the ticket and `targetTicketId` and returns the updated list of linked tickets. Linking a regular ticket to a tracker ticket also archives the regular ticket (it is now tracked by the tracker). Calling it again for an already linked pair is a no-op. # List available export fields Source: https://docs.gleap.io/api-reference/ticket/list-available-export-fields https://api.gleap.io/api-docs.json get /tickets/export-fields Returns the exportable field definitions (`{ fields: [...] }`) for a ticket type; use these keys as `projection[]` values on GET /tickets/csv-export. # List current ticket viewers Source: https://docs.gleap.io/api-reference/ticket/list-current-ticket-viewers https://api.gleap.io/api-docs.json get /tickets/presence/viewers Returns the set of agents currently viewing tickets in the project (presence). Dashboards call this to seed and periodically reconcile viewer avatars, so presence does not depend on keepalive broadcasts. # Mark a ticket as spam Source: https://docs.gleap.io/api-reference/ticket/mark-a-ticket-as-spam https://api.gleap.io/api-docs.json put /tickets/{ticketId}/spam Mark a ticket as spam: flags the ticket (and its merged duplicates) as spam, archives it into the spam tab, and blocks the contact — future tickets from them are auto-flagged as spam and inbound emails from them are dropped unless whitelisted. Undo via unarchive ("Not spam"), which clears the spam flag and unblocks the contact again. # Merge a duplicate group Source: https://docs.gleap.io/api-reference/ticket/merge-a-duplicate-group https://api.gleap.io/api-docs.json put /tickets/deduplicate/merge Merges duplicate feature requests into a main ticket with AI-rewritten content. # Merge multiple tickets into one Source: https://docs.gleap.io/api-reference/ticket/merge-multiple-tickets-into-one https://api.gleap.io/api-docs.json put /tickets/merge Merges `ticketsToMergeIds` into a target ticket and returns the resulting main ticket. `targetTicketId` is required unless `shouldCreateNewTicket` is `true`, in which case a fresh main ticket is created (and an existing target ticket, if given, is archived too). Merged tickets are archived and linked to the main ticket. `shouldMergeTasks` re-parents linked sub-tickets; `shouldMergeContacts` merges the contacts of the merged tickets. # Run workflow Source: https://docs.gleap.io/api-reference/ticket/run-workflow https://api.gleap.io/api-docs.json post /tickets/{ticketId}/workflow Run workflow # Search feature requests semantically Source: https://docs.gleap.io/api-reference/ticket/search-feature-requests-semantically https://api.gleap.io/api-docs.json get /tickets/search-feature-requests Dedupe-style search across the project's `FEATURE_REQUEST` tickets. Uses OpenSearch fuzzy match + Voyage AI rerank — returns the most semantically similar matches to the `query` argument, not literal keyword hits. Use this before filing a new feature request to avoid duplicates. Returns `{ matches: [...] }` with at most 3 reranked matches (archived feature requests and hidden lanes are excluded). # Search for tickets Source: https://docs.gleap.io/api-reference/ticket/search-for-tickets https://api.gleap.io/api-docs.json get /tickets/search Full-text search over the project's tickets and their comments. Returns `{ hits: [...] }` with at most 30 hits, ordered by relevance. Query parameters: `searchTerm` (required, max 100 characters), `type` (optional ticket type filter, e.g. `BUG`), `status` (optional status filter, e.g. `OPEN`), `archived` (optional `true`/`false`; omit to search both), `addSession` (set to `true` to include contact data on each hit). # Send ticket conversation transcript to multiple emails Source: https://docs.gleap.io/api-reference/ticket/send-ticket-conversation-transcript-to-multiple-emails https://api.gleap.io/api-docs.json post /tickets/{ticketId}/send-transcript Send the conversation history of a ticket to a list of email addresses # Send ticket to integration Source: https://docs.gleap.io/api-reference/ticket/send-ticket-to-integration https://api.gleap.io/api-docs.json post /tickets/{ticketId}/send-to-integration Send ticket to integration # Set the composer draft message Source: https://docs.gleap.io/api-reference/ticket/set-the-composer-draft-message https://api.gleap.io/api-docs.json put /tickets/{ticketId}/draft-message Stage a drafted reply in the ticket's dashboard composer. `content` is either a Markdown string (converted server-side to the composer's rich-text format) or a TipTap doc. The draft appears instantly in the composer of everyone viewing the ticket; nothing is sent to the customer. It replaces any previous draft and is cleared automatically when a reply is sent or the draft is dismissed in the composer. # Snooze a ticket Source: https://docs.gleap.io/api-reference/ticket/snooze-a-ticket https://api.gleap.io/api-docs.json put /tickets/{ticketId}/snooze Snoozes a ticket for `duration` seconds: sets `snoozedUntil`, moves the status to `SNOOZED` and clears the unread flag. The ticket reopens automatically when the snooze expires. # Unarchive a ticket Source: https://docs.gleap.io/api-reference/ticket/unarchive-a-ticket https://api.gleap.io/api-docs.json put /tickets/{ticketId}/unarchive Unarchive a ticket in a project. # Unlink a ticket Source: https://docs.gleap.io/api-reference/ticket/unlink-a-ticket https://api.gleap.io/api-docs.json put /tickets/{ticketId}/unlink Unlink a ticket in a project. # Update a ticket Source: https://docs.gleap.io/api-reference/ticket/update-a-ticket https://api.gleap.io/api-docs.json put /tickets/{ticketId} Update a ticket in a project. # Voice reply (dictate or smart) Source: https://docs.gleap.io/api-reference/ticket/voice-reply-dictate-or-smart https://api.gleap.io/api-docs.json post /tickets/{ticketId}/voice-reply Process an operator's recorded audio for a ticket with one multimodal model call. `dictate` returns a verbatim transcript; `smart` treats the audio as spoken keywords and drafts a fluent reply using the ticket + conversation as context (no knowledge-base retrieval). The client uploads the audio via POST /uploads first and passes the resulting URL. # Vote for ticket Source: https://docs.gleap.io/api-reference/ticket/vote-for-ticket https://api.gleap.io/api-docs.json post /tickets/{ticketId}/vote Vote for a ticket. `action` controls semantics: `'toggle'` (default) flips the vote, `'subscribe'` is idempotent add, `'unsubscribe'` is idempotent remove. # Get a single translatable entry Source: https://docs.gleap.io/api-reference/translations/get-a-single-translatable-entry https://api.gleap.io/api-docs.json get /translations/entries/{entryId} Returns the full content of a single translatable entry in the specified language. The entry ID uses the format "type:id" as returned by GET /translations/entries. The id part is a Mongo id for `article`, `collection` and `emailtemplate` (e.g. "article:507f1f77bcf86cd799439011") and the translation key for `statictranslation` (e.g. "statictranslation:welcomeText"). If no language is specified, the project's primary language is used. # List all translatable entries Source: https://docs.gleap.io/api-reference/translations/list-all-translatable-entries https://api.gleap.io/api-docs.json get /translations/entries Returns `{ entries: [...] }` containing every translatable entity for the project (help-center articles, collections, email templates and static translations), each with its field list, source language and available languages. Use the `type` query parameter to filter by entity type. # Update a translatable entry Source: https://docs.gleap.io/api-reference/translations/update-a-translatable-entry https://api.gleap.io/api-docs.json put /translations/entries/{entryId} Pushes a translation for a specific entry and language. The entry ID uses the format "type:id" as returned by GET /translations/entries. The id part is a Mongo id for `article`, `collection` and `emailtemplate` (e.g. "article:507f1f77bcf86cd799439011") and the translation key for `statictranslation` (e.g. "statictranslation:welcomeText"). Only the specified language is updated; other languages are not affected. # Import an image from a URL Source: https://docs.gleap.io/api-reference/uploads/import-an-image-from-a-url https://api.gleap.io/api-docs.json post /uploads/from-url Import an image that is already hosted at a publicly reachable http(s) URL. The server downloads the image, verifies it really is one (PNG, JPEG, GIF, WebP, SVG or BMP; maximum 100 MB), stores a copy on the Gleap CDN, and returns the new permanent `fileUrl`. Useful for migrating help center article images in bulk when the files are already hosted elsewhere — import each image, then reference the returned URLs in the article `content`. URLs that resolve to private or internal network addresses are rejected. # Upload a file Source: https://docs.gleap.io/api-reference/uploads/upload-a-file https://api.gleap.io/api-docs.json post /uploads Upload a file and get back its permanent public URL on the Gleap CDN. Send the request as `multipart/form-data` with the file in a form field named `file` (maximum size 100 MB). Files are stored in a folder scoped to the project passed in the `project` header. The returned `fileUrl` can be used anywhere a URL is accepted — most commonly as the image source inside help center article `content`, which is TipTap JSON where images are nodes of the shape `{ "type": "image", "attrs": { "src": "" } }`. To add images to articles in bulk (e.g. UI screenshots for many articles), call this endpoint once per file, collect the returned URLs, and reference them in the article content when creating or updating articles. # Authenticate a session for websockets Source: https://docs.gleap.io/api-reference/user/authenticate-a-session-for-websockets https://api.gleap.io/api-docs.json post /users/me/session-auth Authenticate a widget session for websocket use. Authenticated with the project's public API key (`api-token` header) plus a signed session identity (`gleap-id`/`gleap-hash` headers), not with a dashboard JWT. # Authorize a session channel subscription Source: https://docs.gleap.io/api-reference/user/authorize-a-session-channel-subscription https://api.gleap.io/api-docs.json post /users/me/session-channel-auth Authorize a websocket subscription to the caller's own `private-session-` channel. Any other channel name returns `{ "valid": false }` with HTTP 200. Authenticated with the project's public API key (`api-token` header) plus a signed session identity (`gleap-id`/`gleap-hash` headers). # Get current user. Source: https://docs.gleap.io/api-reference/user/get-current-user https://api.gleap.io/api-docs.json get /users/me Get the authenticated user. Credentials and internal fields (`password`, `code`, `serviceAccountApiToken`, `marketingTracking`, WebAuthn key material) are never included in the response. # Get current user's role permissions. Source: https://docs.gleap.io/api-reference/user/get-current-users-role-permissions https://api.gleap.io/api-docs.json get /users/me/permissions Returns the roles and effective permissions of the authenticated user, scoped to the `organisationId` query parameter if given, otherwise to the organisation owning the `project` header, otherwise to the first organisation the user is a member of. Responds 404 when the organisation, project or role cannot be resolved. # Get unified inbox ticket Source: https://docs.gleap.io/api-reference/user/get-unified-inbox-ticket https://api.gleap.io/api-docs.json get /users/unified-inbox/{ticketId} Get a single unified-inbox conversation. Returns 404 if the ticket is not of type INQUIRY or the authenticated user has no INQUIRY access to its project. # Get unified inbox tickets Source: https://docs.gleap.io/api-reference/user/get-unified-inbox-tickets https://api.gleap.io/api-docs.json get /users/unified-inbox Get open conversations from every project the authenticated user can access. Only INQUIRY tickets are returned; done, snoozed, archived, spam, hidden and merged-duplicate tickets are excluded. Returns `{ tickets: [...] }`. Query parameters: `type` is a filter preset, one of `my` (or `personalinbox`), `unassigned`, `unread`, `mentioned`, `overdue` (any other value returns all accessible open conversations); `filteredProjectId` restricts to one project; `page` (1-based) and `limit` should be passed together. # Hand over the user's open tickets to their team Source: https://docs.gleap.io/api-reference/user/hand-over-the-users-open-tickets-to-their-team https://api.gleap.io/api-docs.json post /users/me/reassign-tickets Hands over the authenticated user's open conversations to their teammates. Only OPEN tickets that are currently assigned to the user AND belong to a team are affected, at most 100 per call; teams using manual assignment are skipped. Returns `{ success: true }`. # Resend a verification code to the user's email. Source: https://docs.gleap.io/api-reference/user/resend-a-verification-code-to-the-users-email https://api.gleap.io/api-docs.json post /users/resend Resend a verification code to the user's email. # Sign up a new user Source: https://docs.gleap.io/api-reference/user/sign-up-a-new-user https://api.gleap.io/api-docs.json post /users Register a new dashboard user. Sends a 6-digit verification code by email and returns a JWT plus the created (still unconfirmed) user. `email`, `name` and `turnstileToken` are required in practice; a `name` containing a URL is rejected as spam. Rate limited to 30 requests per hour per IP. # Update the current user Source: https://docs.gleap.io/api-reference/user/update-the-current-user https://api.gleap.io/api-docs.json put /users/{userId} Update the authenticated user's own profile. The `{userId}` path segment is ignored; you can only ever update yourself. Sending an empty string for a field clears it; omitted fields are left untouched. # Verify a user's email address Source: https://docs.gleap.io/api-reference/user/verify-a-users-email-address https://api.gleap.io/api-docs.json post /users/verify Confirm a new user's email address with the 6-digit code sent at signup. The code expires 10 minutes after it was issued. On success any pending invitations for that email are accepted and a JWT plus the confirmed user is returned. Rate limited to 30 requests per hour per IP. # Introducing Source: https://docs.gleap.io/documentation/android/README The Gleap SDK for Android is the easiest way to integrate Gleap into your apps. Communicate with your users directly and build better software by discovering their everyday pain points. Gleap is your all-in-one customer feedback tool for apps and websites. For the SDK to work, you need an API key, which you can get for free at [app.gleap.io](https://app.gleap.io). ## 🏗 Installation Gleap is distributed through the [maven](https://mvnrepository.com). Add the following to you build.gradle (Module: app). ```javascript theme={null} implementation group: 'io.gleap', name: 'gleap-android-sdk', version: '17.0.0' ``` The Gleap SDK is now almost successfully installed. **Let's carry on with the initialization** 🎉 ### 👷‍♂️ Initialize & configure the SDK Open your preferred development tool and add the following code to your main activity (typically MainActivity.java). ``` import io.gleap.Gleap; ``` These two includes are everything you need. ``` @Override protected void onCreate(Bundle savedInstanceState) { .... Gleap.initialize("YOUR_API_KEY", this); } ``` You are all set now! **Run the app and report your first bug 🎉.** Get your API key [here](https://app.gleap.io). ## Required permissions In order to use the image picker for attachments, add the following permissions to your `AndroidManifest.xml`. ``` ``` The following permissions are needed to enable audio recordings. ``` ``` The following permissions are needed for our video call feature: ## 🤝 Need help? We are here to help, simply drop us an email at [hello@gleap.io](mailto:hello@gleap.io). # Frontend tools Source: https://docs.gleap.io/documentation/android/aitools Frontend tools let your AI agent execute actions directly inside your app — initiating a transfer, resetting a password, cancelling an order, etc. Tools are defined on your AI agent in the Gleap dashboard (**AI agent > Tools > Frontend tool**) — name, description, parameters and execution mode all live there. Your app only registers a handler that executes the tool. Learn how to set up Frontend tools in our [help center article](https://help.gleap.io/en/articles/221-frontend-tools-let-the-ai-run-actions-in-your-app). ## Register a tool handler Register the handler for a dashboard-defined Frontend tool. Use the tool's runtime name shown in the tool editor. ```java theme={null} Gleap.getInstance().registerAgentTool("send-money", new GleapAgentToolHandler() { @Override public void execute(JSONObject params, GleapAgentToolResultCallback callback) { String amount = params.optString("amount"); String contact = params.optString("contact"); // Run your own logic here. // Return a string or JSON — the AI waits for this response. callback.onResult("The transfer was initiated. The user must confirm it in the banking app."); } }); ``` Or with Kotlin: ```kotlin theme={null} Gleap.getInstance().registerAgentTool("send-money") { params, callback -> val amount = params.opt("amount") // Run your own logic here. // Return a string or JSON — the AI waits for this response. callback.onResult("The transfer was initiated. The user must confirm it in the banking app.") } ``` **Handler contract** * The handler receives the parameters configured in the dashboard as a `JSONObject`, filled with the values the AI collected. * Call the callback exactly once with the result — a `String` or a `JSONObject` / `JSONArray` (stringified automatically). The result is sent back to the AI, which uses it to reply. * The callback can be invoked asynchronously from any thread — the AI waits for it. * Exceptions thrown by the handler are caught and reported to the AI automatically. * If no handler is registered for a tool, the AI is informed so it can respond accordingly. ## Execution modes Set per tool in the dashboard: * `Auto` — the handler runs immediately when the AI calls the tool. * `Ask before final execution` — the AI adds a confirmation button to its reply; the handler only runs after the user confirms. ## Migrating from `setAiTools` `Gleap.getInstance().setAiTools(...)` and the `GleapAiTool` / `GleapAiToolParameter` classes have been removed. Tools defined via `setAiTools` could only return a static response to the AI — Frontend tools execute real code and return live results. Define your tools on the AI agent in the dashboard and register their handlers via `registerAgentTool(name, handler)` instead. The `setAiToolExecutedCallback` callback remains available. # Audio recording Source: https://docs.gleap.io/documentation/android/audio-recording Available starting from version 14.2.0. Gleap allows users to record audio messages when chatting with support. This is a great way to collect feedback from users. ## Additional setup In order for audio recording to work for Android, you need to add the following keys to your `AndroidManifest.xml` file: ```xml theme={null} ``` This key is required by Android to allow the app to use the microphone. ## Enable the audio recording feature To enable the audio recording feature, navigate to `AI chatbot` -> `Settings` and toggle the `Allow audio messages` switch. # Checklists Source: https://docs.gleap.io/documentation/android/checklists Dive into a completely refreshed onboarding experience that will guide your users with gusto. The new checklist feature not only ensures your users are thoroughly onboarded but also keeps them deeply engaged. All of this is neatly packed inside our Gleap widget! ## Open the checklists overview Open the checklists overview with the method below. ```javascript theme={null} Gleap.getInstance().openChecklists(true); ``` ## Manually start a checklist Checklists can be sent either through trigger rules or manually with the method below. ```js theme={null} Gleap.getInstance().startChecklist("outboundId", true); ``` You can find the outboundId within the checklist editor. Please note that SDK version 12.1.0 or higher is required to send checklists. # Console logs Source: https://docs.gleap.io/documentation/android/console-logs The Gleap Android SDK collects console logs by default. Further more you can make use of our custom logs, which offer more control over the logs. ## Disable default console logs It is possible to disable the default collection of console logs by calling the following method prior to the initialization of Gleap. ``` Gleap.getInstance().disableConsoleLog(); ``` ## Custom logs Custom logs allow you to create logs in the Gleap activity log. There are three severnity types available for logs: `ERROR`, `WARNING` and `INFO`. ``` Gleap.getInstance().log("This is a test log."); ``` By default logs will be created with the severnity `INFO`. Use the following method to explicitly set the severnity. ``` Gleap.getInstance().log("This is a test error.", GleapLogLevel.ERROR); ``` # Conversations Source: https://docs.gleap.io/documentation/android/conversations Conversations ## Start a new conversation You can manually start a new conversation with the following method: ```javascript theme={null} Gleap.getInstance().startConversation(true); ``` Open the conversation history If you'd like to manually show the conversation history of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.getInstance().openConversations(); ``` # Custom actions Source: https://docs.gleap.io/documentation/android/custom-actions We know that the built in actions (Bug Reporting, Feature Requests, Ratings & Contact Us) might not be enough for certain use cases. For these situations we offer custom actions, which allow you to start any custom action by code. ## Configure a custom action The first step with custom actions is to open the visual widget configurator and select **"Custom action"** as action type. Now you need to **set a name for your custom action**. Choose any name you like (it's however important that this name matches the name you check in the next step). Setup custom actions in the Gleap dashboard. !\[Setup custom actions in the Gleap dashboard. ]\(./images/image (5).png) ## Custom action callback Once you set a custom action in the Gleap dashboard, it will be called automatically on selection through the user. In order to perform custom code, simply implement our `CustomActionCallback` to receive the custom action events. ### Add & implement the Gleap delegate The following code sample shows how to implement the `CustomActionCallback` protocol. ```java theme={null} Gleap.getInstance().registerCustomAction(new CustomActionCallback() { @Override public void invoke(String customAction, String shareToken) { // For custom actions triggered within tickets, shareToken will be set to identify the ticket. if (customAction == "MAGIC_ACTION") { System.out.println("Magic action got called."); } } }); ``` The **custom action name** is defined by you in the visual widget configurator on the Gleap dashboard. # Custom data Source: https://docs.gleap.io/documentation/android/custom-data ## Add custom data In many situations you may want to attach custom data to feedback items in order to better understand the context. You can add custom data incrementally or all at once. Any simple dictionary can be attached. ```java theme={null} Gleap.getInstance().setCustomData("hello@bugbattle.io", "email"); ``` ## Append custom data If you want to attach custom data incrementally, you can do so with the `attachUserAttribute` method. ```java theme={null} JSONObject jsonObject = new JSONObject(); Gleap.getInstance().attachCustomData(jsonObject); ``` ## Remove custom data Remove custom data key value pairs by calling the following method. ```java theme={null} Gleap.getInstance().removeCustomDataForKey("email"); ``` ## Clear all custom data It's possible to clear all attached custom data by calling the following method. ```java theme={null} BugBattle.getInstance().clearCustomData(); ``` # Custom URL handler Source: https://docs.gleap.io/documentation/android/custom-url-handler There are scenarios where you need complete control over the behavior of hyperlink actions within your application. The method described below enables you to override the default URL handler. By setting a new URL handler, the Gleap framework will no longer manage URL openings automatically. Instead, it will invoke your custom callback function, giving you the freedom to handle URL interactions according to your specific requirements. ## Configure the URL handler ```javascript theme={null} Gleap.getInstance().registerCustomLinkHandler(new CustomLinkHandlerCallback() { @Override public void invoke(String url) { // Insert your URL handling logic here } }); ``` # Callbacks Source: https://docs.gleap.io/documentation/android/events Use our GleapDelegate to get notified on certain state changes of the Gleap widget. This enables you to create an even deeper integration with Gleap. ```java theme={null} Gleap.getInstance().setNotificationUnreadCountUpdatedCallback(new NotificationUnreadCountUpdatedCallback() { @Override public void invoke(int count) { // Notification count updated. } }); Gleap.getInstance().setWidgetOpenedCallback(new WidgetOpenedCallback() { @Override public void invoke() { // called when the widget is opened } }); Gleap.getInstance().setWidgetClosedCallback(new WidgetClosedCallback() { @Override public void invoke() { // called when the widget is closed } }); Gleap.getInstance().setInitializedCallback(new InitializedCallback() { @Override public void initialized() { // called when Gleap is successfully initialized } }); Gleap.getInstance().setConfigLoadedCallback(new ConfigLoadedCallback() { @Override public void configLoaded(JSONObject jsonObject) { // called when the config is loaded from the server successfully } }); Gleap.getInstance().setFeedbackSentCallback(new FeedbackSentCallback() { @Override public void invoke(String message) { // called when the feedback is sent successfully } }); Gleap.getInstance().setFeedbackSendingFailedCallback(new FeedbackSendingFailedCallback() { @Override public void invoke(String message) { // called when the sending of the feedback failed } }); Gleap.getInstance().registerCustomAction(new CustomActionCallback() { @Override public void invoke(String message) { // called when a custom action from the widget is issued } }); Gleap.getInstance().setFeedbackFlowStartedCallback(new FeedbackFlowStartedCallback() { @Override public void invoke(String message) { // called when the form is started, not only the widget is opened } }); Gleap.getInstance().InitializationDoneCallback(new InitializationDoneCallback() { @Override public void invoke() { // called when the sdk is initialize }); ``` # Feature requests Source: https://docs.gleap.io/documentation/android/feature-requests The new Gleap widget offers a feature request view allowing users to view, upvote & comment more easily on feature requests. Release notes and news for your app or website You can enable the feature requests view directly within the Gleap Dashboard or show it by code. ## Open the feature requests app by code If you'd like to manually show the feature requests app of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.getInstance().openFeatureRequests(false); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # Feedback button Source: https://docs.gleap.io/documentation/android/feedback-button In some situations you might want to take full control over the feedback button. In order to show or hide the feedback button, you can simply use the following methods. ### Show the feedback button ```javascript theme={null} Gleap.getInstance().showFeedbackButton(true); ``` ### Hide the feedback button ```javascript theme={null} Gleap.getInstance().showFeedbackButton(false); ``` # Forms Source: https://docs.gleap.io/documentation/android/feedback-flows Gleap forms are a traditional, straightforward approach for user data input. They offer a simple, efficient method for users to provide specific information or feedback. Forms are particularly useful when detailed user input is essential, allowing for a clear, direct way of data collection without the dynamic steps involved in workflows. This makes forms a reliable option for scenarios where straightforward, user-provided data is key. If you want to manually show a form, simply call one of the following methods. ### Bug reporting form The bug reporting form is the default form for bug reports and allows users to mark bugs and add a description as well as their email address. ```javascript theme={null} // Starts a classic bug reporting form. Gleap.getInstance().startClassicForm("bugreporting", true); ``` The first parameter determines the flow that should be started. The second parameter allows you to pass the `showBackButton` form option. ### Feature request form This form is great if you want to collect feature requests. You can also embed your Gleap roadmap and share it with your users to have them vote on requests. ```javascript theme={null} // Starts a classic feature request form. Gleap.getInstance().startClassicForm("featurerequests", true); ``` ### Custom forms Gleap also allows you to configure custom forms. This is especially handy if our default forms don't fully cover your use cases. Visit our dashboard for more information on custom forms. Classic forms ```javascript theme={null} // Starts a classic form with the CUSTOM_FORM_KEY as key. Gleap.getInstance().startClassicForm("CUSTOM_FORM_KEY", true); ``` # Help center Source: https://docs.gleap.io/documentation/android/helpcenter Happier customers, fewer support questions. What’s not to like? Make it easy for users to access information with our help center articles. Release notes and news for your app or website **Show help center articles** directly within the **Gleap widget**, to offer customers the help they need at the right place & time. ## Open the help center by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.getInstance().openHelpCenter(false); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a help center article by code If you'd like to open a help center article directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.getInstance().openHelpCenterArticle("articleId", false); ``` *The first parameter **articleId** can be found at the bottom of your article editor in the **Share this article** banner.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a help center collection by code If you'd like to open a collection directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.getInstance().openHelpCenterCollection("collectionId", false); ``` *The first parameter **collectionId** can be found at the bottom of collection in the **Share this collection** banner.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Search your help center If you'd like to search for help articles, you can do so by calling the following method: ```javascript theme={null} Gleap.getInstance().searchHelpCenter("Search term", false); ``` *The first parameter **term** defines the search term, the Gleap SDK will look for to find related articles.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # In-app notifications Source: https://docs.gleap.io/documentation/android/in-app-push-notifications With Gleap, in-app notifications appear directly within the app when a new message is sent to a customer who has the app open. The same applies to news updates. We also support push notification. Please see the push notifications documentation for more information on it. ## Disable in-app notifications The following method allows you to disable the in app notifications. ```js theme={null} Gleap.setDisableInAppNotifications(true); ``` ## Notification container offset You can adjust the position of the in-app notification container by setting an offset in pixels: ```java theme={null} Gleap.getInstance().setNotificationContainerOffset(x, y); ``` * **x** – Horizontal offset in pixels (positive values move the container to the right). * **y** – Vertical offset in pixels (positive values move the container down). # Network logs Source: https://docs.gleap.io/documentation/android/network-logs Gleap allows you to monitor all network requests for a better understanding of what's happening within your apps. It can be done manually by passing the data to Gleap or if you're using OkHttp with the Gleap OkHttpInterceptor. ## Logging HttpUrlConnection requests There are several ways to log the network with HttpUrlConnection. The recommended way is to use the following method. All information from the connection is automatically gathered for you. The **requestBody** and **result** can be passed on as **JSON** or **String.** ```java theme={null} Gleap.getInstance().logNetwork((HttpsURLConnection) conn, requestBody, result); ``` Let's have a more detailed example. This request posts data to an endpoint. ```java theme={null} .... @Override protected Object doInBackground(Object[] objects) { HttpURLConnection conn = null; JSONObject result = null; try { URL url = new URL("YOUR_URL"); conn = (HttpURLConnection) url.openConnection(); conn.setRequestProperty("Accept", "application/json"); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestMethod("POST"); JSONObject requestBody = new JSONObject(); try { requestBody.put("Key", "Value"); requestBody.put("Key2", "Value"); } catch (JSONException e) { e.printStackTrace(); } try (OutputStream os = conn.getOutputStream()) { byte[] input = requestBody.toString().getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } try (BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream(), "utf-8"))) { String input; while ((input = br.readLine()) != null) { result = new JSONObject(input); } } catch (JSONException e) { e.printStackTrace(); } Gleap.getInstance().logNetwork((HttpsURLConnection) conn, requestBody, result); } catch(Exception e) { e.printStackTrace(); } ``` ## OkHttp There is an easy way to intercept all requests from [OkHttp](https://square.github.io/okhttp/). This will be logged automatically by Gleap. First of all, import the OkHttp interceptor for Gleap in your **build.gradle(root)**. ```java theme={null} implementation group: 'io.gleap', name: 'gleap-okhttp-interceptor', version: '7.4.1' ``` The interceptor can be used like this: ```java theme={null} OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new GleapOkHttpInterceptor()) .build(); Request request = new Request.Builder() .url("http://www.publicobject.com/helloworld.txt") .header("User-Agent", "OkHttp Example") .build(); Response response = client.newCall(request).execute(); response.body().close(); ``` ## Other Libraries If you are using any other library than HTTPUrlConnection or OkHttp you can manually log any requests with the following method. ```java theme={null} void logNetwork("YOUR_URL", RequestType.GET, 200, 150, requestBody, response); ``` ## Filtering network logs Gleap allows you to strip off specific key/value pairs from network logs. This empowers you to easily remove sensitive data like `tokens, passwords` or `usernames`. ### How does it work? Log in to the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now enable the `network log filters` option (within the advanced options tab). Once the option is enabled, you can add multiple keys to the array bellow, which should be excluded. All keys, which you add to the exclusion list, will be loaded together with the widget configuration. Before sending a feedback item to our backend, the client SDK will loop through all network requests and stripe off all matching key/value pairs from the `request headers`, `header-payload` (if it's a JSON) and `response body` (if it's a JSON). This ensures that sensitive information will never even leave the client application. #### Example: If you want to remove the Authorization bearer token from your requests, simply add "Authorization" to the list of keys. Network log filters ### Set filter with code It's also possible to set the network log filters by code. ```javascript theme={null} // Manually set the network logs filters Gleap.getInstance().setNetworkLogPropsToIgnore([ "api-key", "user.password", "...", ]); ``` ## Blacklisting URLs It is possible to blacklist URLs or parts of URLs. If a network request matches one of the entries in the blacklist, the network request won't be included in the network logs. To add a new entry to the blacklist, simply navigate to your project in the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now click on `Developer options` and add the desired URLs. ### Set blacklist with code It's also possible to set the network log blacklist by code. ```javascript theme={null} // Manually set the network logs blacklist Gleap.getInstance().setNetworkLogsBlacklist(["https://api.gleap.io", "..."]); ``` # Prefill the widget form Source: https://docs.gleap.io/documentation/android/prefill-form-data In some situations you might want to prefill some fields for the user. This can be achieved by the following method. ```java theme={null} JSONObject prefill = new JSONObject(); try{ prefill.put("description", "Prefill the description with this."); }catch (Exception ex){ ex.getStackTrace(); } PrefillHelper.getInstancen().setPrefillData(prefill); ``` You need to pass a key value pair to the `setPrefillData`. The key is the form identifier, which can be found under the 'Advanced' section of a question. (see screenshot for an example) Form identifier # Push notifications Source: https://docs.gleap.io/documentation/android/push-notifications Stay connected with your customers by utilizing push notifications to alert them of new chat messages, release notes, and news articles. This will deepen engagement and foster stronger relationships. Gleap supports Firebase Cloud Messaging to send push notifications to users. ## Setup Firebase Cloud Messaging To make use of Gleap Push Notifications you must add the Firebase Cloud Messaging service to your app or website. Learn how to get started with FCM here. ## Getting your Firebase Cloud Messaging Token Open your project in Firebase and open the project settings. Click on "Cloud Messaging" and, if it is not already enabled, activate the Firebase Cloud Messaging API (V1). Gleap Firebase Setup Proceed to the "Service Accounts" section and generate a new private key, which will automatically create a file named like `serviceAccountKey.json`. Gleap Firebase Setup Next, open the project settings in Gleap, select "Push Notifications", and upload the `serviceAccountKey.json` file. Finally, save your configuration. Gleap Push Notifications Setup ## Subscribe to the Gleap user topic The last step to complete the push notification setup is to subscribe to the user topic, which Gleap will send the push notifications to. In order to do so, you will need to register the register & unregister push message topic callbacks. ```js theme={null} // Learn more on: // https://firebase.google.com/docs/cloud-messaging/android/topic-messaging import io.gleap.callbacks.RegisterPushMessageGroupCallback; import io.gleap.callbacks.UnRegisterPushMessageGroupCallback; import com.google.firebase.messaging; Gleap.getInstance().setRegisterPushMessageGroupCallback(new RegisterPushMessageGroupCallback() { @Override public void invoke(String pushMessageGroup) { FirebaseMessaging.getInstance().subscribeToTopic(pushMessageGroup) .addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { // All done. } }); } }); Gleap.getInstance().setUnRegisterPushMessageGroupCallback(new UnRegisterPushMessageGroupCallback() { @Override public void invoke(String pushMessageGroup) { FirebaseMessaging.getInstance().unsubscribeFromTopic(pushMessageGroup) .addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { // All done. } }); } }); ``` That's it - build and run your app 🚀 ## Handle push-notifications click In order to open the message, the user clicked on, you will need to add some extra code to your app. The idea is to get the data from the push notification and then pass it to the SDK by utilizing handlePushNotification(). ```js theme={null} import android.os.Bundle import org.json.JSONObject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch /** * Extension function to convert a Bundle to a JSONObject. */ fun Bundle?.toJsonObject(): JSONObject { val jsonObject = JSONObject() this?.let { for (key in it.keySet()) { val value = it.get(key) jsonObject.put(key, value) } } return jsonObject } // Usage within a CoroutineScope. You usually want to put this inside you onCreate function. CoroutineScope(Dispatchers.Main).launch { if (intent?.extras?.getString("sender") == "GLEAP") { Gleap.getInstance().handlePushNotification(intent.extras.toJsonObject()) } } ``` ## Notification images When a changelog or news article with a featured image is sent as a push notification, Gleap includes the image as `notification.image` in the FCM payload. On Android, Firebase Cloud Messaging displays the image automatically when the notification is delivered while your app is in the background — no additional setup is required. # Release notes & news Source: https://docs.gleap.io/documentation/android/release-notes-and-news Gleap allows you to share release notes & news articles with your customers. Release notes and news for your app or website You can send release notes & news directly within the Gleap Dashboard. Once sent, the user gets notified when he starts his next session. ## Open the news section by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.getInstance().openNews(false); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # Surveys Source: https://docs.gleap.io/documentation/android/surveys Gleap allows you to create micro surveys to be run directly in your Gleap widget. We offer templates for some of the most common survey types, such as NPS scores, product market fit or product satisfaction. ## Sending surveys with triggers Usually customers use triggers to send surveys. Example use cases for that include: * Sending surveys after a certain amount of time * Sending a survey on a certain page * Sending a survey after a specific event happened * ... In order to get started with survey triggers, you need to start tracking events. Once an event has been tracked, you can use it as trigger in the survey options. You can find more information about tracking events [here](./track-events). Gleap survey triggers ## Manually sending surveys You can also manually send surveys to your users. For this you only need to call the following method: ```javascript theme={null} Gleap.getInstance().showSurvey(surveyId, SurveyType.SURVEY); ``` The first parameter is the survey id, the second parameter is the format of the survey. The format can be either `SurveyType.SURVEY` (default: card style survey) or `SurveyType.SURVEY_FULL` (full screen survey). Please note that the Gleap SDK needs to be fully initialized to be able to show a survey. # Tags Source: https://docs.gleap.io/documentation/android/tags Gleap allows you to set tags with every feedback item sent from the SDK. To set tags, simply pass an array of Strings to the `setTags` method of the SDK. ## Set tags Set tags to be sent with every feedback item. ```javascript theme={null} Gleap.getInstance().setTags(["iOS", "Subscribed"]); ``` If you want to update or remove the tags, simply call the method with the updated string array. # Ticket attributes Source: https://docs.gleap.io/documentation/android/ticket-attributes Ticket custom data ## Set ticket attributes Ticket attributes can be set with the method below. If the user also provides data for an attribute (for example `description`), the user input will be prioritized. ```javascript theme={null} Gleap.getInstance().setTicketAttribute("notes", "This is a test value."); ``` **First param**: attribute key
**Second param**: value (string, boolean, string array or number are supported) Ticket attribute data will not be [pre-filled](android/prefill-form-data.md) in forms. ## Finding the ticket attribute keys You can find or create all available ticket attributes for each ticket type in **Settings** > **Data attributes**. Ticket attribute ## Unset ticket attributes Ticket attributes can be unset with the method below. ```javascript theme={null} Gleap.getInstance().unsetTicketAttribute("notes"); ``` ## Clear all ticket attributes All ticket attributes can be cleared with the method below. ```javascript theme={null} Gleap.getInstance().clearTicketAttributes(); ``` # Track pages Source: https://docs.gleap.io/documentation/android/track-pages The Android SDK tracks pages based on the activity name by default. If you want to customize the tracked pages you can do so by using the trackEvent() method below to track custom pages. ## Track a page ```java theme={null} JSONObject data = new JSONObject(); try { data.put("page", "Example page"); } catch (JSONException e) { e.printStackTrace(); } Gleap.getInstance().trackEvent("pageView", data); ``` You will be able to use the tracked pages as triggers in outbound messages as well as breadcrumbs for debugging. # Translations Source: https://docs.gleap.io/documentation/android/translations Gleap was built for people around the world and offers translations for many languages by default. If we are missing a language or translation, you can simply add an additional language yourself in our visual widget configurator. Gleap automatically picks the device language as default language. If the device language is not available it will switch to English as a fallback. In some situations you might want to overwrite the device language with a custom language. This can be achieved with the following method. ### Overwrite the default language ```swift theme={null} // 2 digit ISO code Gleap.setLanguage("es"); // 5 digit ISO code with lang - country Gleap.setLanguage("en-US"); ``` Please use the `setLanguage` method only before the initialization of the Gleap SDK (before calling `Gleap.initialize()`) # User identity Source: https://docs.gleap.io/documentation/android/user-identity The Gleap identify call lets you tie a user to their feedback items. It includes a unique User ID and optional meta information such as email & name. ### Identify your users To effectively manage your contacts, we advise using `Gleap.getInstancen().identifyContact()` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `Gleap.getInstancen().updateContact()`. This method allows for seamless real-time updates to contact details. Identify your user by calling the following method. ```javascript theme={null} GleapSessionProperties sessionProperties = new GleapSessionProperties(); sessionProperties.setEmail("franzi@gleap.io"); sessionProperties.setName("Franzi"); sessionProperties.setPhone("+1 (902) 123123"); sessionProperties.setValue(199.95); sessionProperties.setPlan("Pro plan"); sessionProperties.setCompanyName("ACME inc."); sessionProperties.setCompanyId("193948"); sessionProperties.setAvatar("https://.../avatar.png"); JSONObject jsonObject = new JSONObject(); jsonObject.put("key1", "data one"); jsonObject.put("key2", "data two"); sessionProperties.setCustomData(jsonObject); Gleap.getInstancen().identifyContact("user_ID", sessionProperties); ``` When transmitting custom data, only primitive numeric and string values are supported for later use in segment filters. Please note that you can send only 35 custom data keys with an identify call. We currently only allow JSON strings, numbers and boolean values as custom data. Gleap defaults to guest sessions when feedback items get reported without calling the identify method first. All feedback items of an existing guest session are merged with the user session once you've identified it. ### Enforce identity verification Enforce identity verification to prevent third parties from impersonating logged-in users. [Learn how to generate the user hash](../guides/enforce-identity-verification) ```javascript theme={null} GleapSessionProperties sessionProperties = new GleapSessionProperties(); sessionProperties.setEmail("franzi@gleap.io"); sessionProperties.setName("Franzi"); sessionProperties.setPhone("+1 (902) 123123"); sessionProperties.setPlan("Pro plan"); sessionProperties.setCompanyName("ACME inc."); sessionProperties.setCompanyId("193948"); sessionProperties.setAvatar("https://.../avatar.png"); sessionProperties.setValue(199.95); // Sets the matching user hash. sessionProperties.setHash(call.argument("userHash")); Gleap.getInstancen().identifyContact("user_ID", sessionProperties); ``` ### Update contact properties To effectively manage your contacts, we advise using `Gleap.getInstancen().identifyContact()` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `Gleap.getInstancen().updateContact()`. This method allows for seamless real-time updates to contact details. ```javascript theme={null} GleapSessionProperties sessionProperties = new GleapSessionProperties(); sessionProperties.setPlan("Pro plan"); sessionProperties.setValue(199.95); Gleap.getInstancen().updateContact(sessionProperties); ``` The updateContact method takes in the same contact parameters as the identify method. Partial updates are possible. ```javascript theme={null} GleapSessionProperties sessionProperties = new GleapSessionProperties(); sessionProperties.setEmail("franzi@gleap.io"); sessionProperties.setName("Franzi"); sessionProperties.setPhone("+1 (902) 123123"); sessionProperties.setPlan("Pro plan"); sessionProperties.setCompanyName("ACME inc."); sessionProperties.setCompanyId("193948"); sessionProperties.setAvatar("https://.../avatar.png"); sessionProperties.setValue(199.95); Gleap.getInstancen().updateContact(sessionProperties); ``` ### Clear the identity on logout We recommend to clear the identity once the user logs out. Clearing the identity will automatically detach the current session and create a new guest session. ```js theme={null} Gleap.getInstance().clearIdentity(); ``` ### Get the identification status of a user With the following method, you can get the status of the current user identity. ```js theme={null} Gleap.getInstance().isUserIdentified(); ``` ### Get the current user identity With the following method, you can get the current user identity. ```js theme={null} Gleap.getInstance().getIdentity(); ``` # Introducing Source: https://docs.gleap.io/documentation/cordova/README The Gleap SDK for Cordova is the easiest way to integrate Gleap into your apps. Communicate with your users directly and build better software by discovering their everyday pain points. Gleap is your all-in-one customer feedback tool for apps and websites. For the SDK to work, you need an API key, which you can get for free at [app.gleap.io](https://app.gleap.io). ## 🏗 Installation Install the **Gleap** package via the cordova CLI. ```js theme={null} cordova plugin add cordova-plugin-gleap ``` Initialize the Gleap SDK on device ready. ```js theme={null} function onDeviceReady() { // Cordova is now initialized. // Initialize the Gleap SDK & have fun! cordova.plugins.GleapPlugin.initialize("YOUR_API_KEY"); } ``` The Gleap Cordova plugin works for both **Android** and **iOS**. Please have a look into our [JavaScript SDK](/javascript/) to learn how to include Gleap into your web app. ## 🤝 Need help? We are here to help! [hello@gleap.io](mailto:hello@gleap.io) # Audio recording Source: https://docs.gleap.io/documentation/cordova/audio-recording Available starting from version 14.2.0. Gleap allows users to record audio messages when chatting with support through our cordova SDK. This is a great way to collect feedback from users. ## iOS setup In order for audio recording to work for iOS, you need to add the following key to your `Info.plist` file: ```xml theme={null} NSMicrophoneUsageDescription We need access to the microphone to record audio messages. ``` This key is required by iOS to allow the app to use the microphone. ## Android setup In order for audio recording to work for Android, you need to add the following keys to your `AndroidManifest.xml` file: ```xml theme={null} ``` This key is required by Android to allow the app to use the microphone. ## Enable the audio recording feature To enable the audio recording feature, navigate to `AI chatbot` -> `Settings` and toggle the `Allow audio messages` switch. # Checklists Source: https://docs.gleap.io/documentation/cordova/checklists Dive into a completely refreshed onboarding experience that will guide your users with gusto. The new checklist feature not only ensures your users are thoroughly onboarded but also keeps them deeply engaged. All of this is neatly packed inside our Gleap widget! ## Open the checklists overview Open the checklists overview with the method below. ```js theme={null} Gleap.openChecklists(); ``` ## Manually start a checklist Checklists can be sent either through trigger rules or manually with the method below. ```js theme={null} Gleap.startChecklist("outboundId"); ``` You can find the outboundId within the checklist editor. Please note that SDK version 12.1.0 or higher is required to send checklists. # Console logs Source: https://docs.gleap.io/documentation/cordova/console-logs The Gleap SDK collects console logs by default. Further more you can make use of our custom logs, which offer more control over the logs. ## Custom logs Custom logs allow you to create logs in the Gleap activity log. There are three severnity types available for logs: `ERROR`, `WARNING` and `INFO`. ```js theme={null} cordova.plugins.GleapPlugin.log("This is a test custom log."); ``` By default logs will be created with the severnity `INFO`. Use the following method to explicitly set the severnity. ```js theme={null} cordova.plugins.GleapPlugin.log( "This is a test custom log WARNING.", "WARNING" ); ``` # Conversations Source: https://docs.gleap.io/documentation/cordova/conversations Conversations ## Start a new conversation You can manually start a new conversation with the following method: ```javascript theme={null} Gleap.startConversation(true); ``` Open the conversation history If you'd like to manually show the conversation history of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openConversations(); ``` # Custom data Source: https://docs.gleap.io/documentation/cordova/custom-data ## Add custom data In many situations you may want to attach custom data to feedback items in order to better understand the context. You can add custom data incrementally or all at once. Any simple JSON object can be attached. ```js theme={null} cordova.plugins.GleapPlugin.attachCustomData({ test1: "Battle", data2: "Unicorn", }); ``` ## Append custom data If you want to attach custom data incrementally you can do so with the `setCustomData` method. ```js theme={null} cordova.plugins.GleapPlugin.setCustomData("email", "lukas@bugbattle.io"); ``` ## Remove custom data Remove custom data key value pairs by calling the following method. ```js theme={null} cordova.plugins.GleapPlugin.removeCustomData("email"); ``` ## Clear all custom data It's possible to clear all attached custom data by calling the following method. ```js theme={null} cordova.plugins.GleapPlugin.clearCustomData(); ``` # Feature requests Source: https://docs.gleap.io/documentation/cordova/feature-requests The new Gleap widget offers a feature request view allowing users to view, upvote & comment more easily on feature requests. Release notes and news for your app or website You can enable the feature requests view directly within the Gleap Dashboard or show it by code. ## Open the feature requests app by code If you'd like to manually show the feature requests app of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} cordova.plugins.GleapPlugin.openFeatureRequests(false); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # Feedback button Source: https://docs.gleap.io/documentation/cordova/feedback-button In some situations you might want to take full control over the feedback button. In order to show or hide the feedback button, you can simply use the following methods. ### Show the feedback button ```javascript theme={null} cordova.plugins.GleapPlugin.showFeedbackButton(true); ``` ### Hide the feedback button ```javascript theme={null} cordova.plugins.GleapPlugin.showFeedbackButton(false); ``` Gleap feedback button with live chat bubble # Forms Source: https://docs.gleap.io/documentation/cordova/feedback-flows Gleap forms are a traditional, straightforward approach for user data input. They offer a simple, efficient method for users to provide specific information or feedback. Forms are particularly useful when detailed user input is essential, allowing for a clear, direct way of data collection without the dynamic steps involved in workflows. This makes forms a reliable option for scenarios where straightforward, user-provided data is key. If you want to manually show a form, simply call one of the following methods. ### Bug reporting form The bug reporting form is the default form for bug reports and allows users to mark bugs and add a description as well as their email address. ```javascript theme={null} // Starts a classic bug reporting form. cordova.plugins.GleapPlugin.startClassicForm("bugreporting", true); ``` The first parameter determines the flow that should be started. The second parameter allows you to pass the `showBackButton` form option. ### Feature request form This form is great if you want to collect feature requests. You can also embed your Gleap roadmap and share it with your users to have them vote on requests. ```javascript theme={null} // Starts a classic feature request form. cordova.plugins.GleapPlugin.startClassicForm("featurerequests"); ``` ### Custom forms Gleap also allows you to configure custom forms. This is especially handy if our default forms don't fully cover your use cases. Visit our dashboard for more information on custom forms. Classic forms ```javascript theme={null} // Starts a classic form with the CUSTOM_FORM_KEY as key. cordova.plugins.GleapPlugin.startClassicForm("CUSTOM_FORM_KEY"); ``` # Help center Source: https://docs.gleap.io/documentation/cordova/helpcenter Happier customers, fewer support questions. What’s not to like? Make it easy for users to access information with our help center articles. Release notes and news for your app or website **Show help center articles** directly within the **Gleap widget**, to offer customers the help they need at the right place & time. ## Open the help center by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} cordova.plugins.GleapPlugin.openHelpCenter(false); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a help center article by code If you'd like to open a help center article directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} cordova.plugins.GleapPlugin.openHelpCenterArticle("articleId", false); ``` *The first parameter **articleId** can be found at the bottom of your article editor in the **Share this article** banner.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a help center collection by code If you'd like to open a collection directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} cordova.plugins.GleapPlugin.openHelpCenterCollection("collectionId", false); ``` *The first parameter **collectionId** can be found at the bottom of collection in the **Share this collection** banner.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Search your help center If you'd like to search for help articles, you can do so by calling the following method: ```javascript theme={null} cordova.plugins.GleapPlugin.searchHelpCenter("Search term", false); ``` *The first parameter **term** defines the search term, the Gleap SDK will look for to find related articles.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # Network logs Source: https://docs.gleap.io/documentation/cordova/network-logs Gleap allows you to log all network requests, to get a better understanding of what went wrong. This usually works out of the box and can be enabled within our visual widget configurator. !\[Netowork logs within the Visual Widget Configurator]\(./images/Bildschirmfoto 2021-12-14 um 10.47.18.png) ## Filtering network logs Gleap allows you to strip off specific key/value pairs from network logs. This empowers you to easily remove sensitive data like `tokens, passwords` or `usernames`. ### How does it work? Log in to the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now enable the `network log filters` option (within the advanced options tab). Once the option is enabled, you can add multiple keys to the array bellow, which should be excluded. All keys, which you add to the exclusion list, will be loaded together with the widget configuration. Before sending a feedback item to our backend, the client SDK will loop through all network requests and stripe off all matching key/value pairs from the `request headers`, `header-payload` (if it's a JSON) and `response body` (if it's a JSON). This ensures that sensitive information will never even leave the client application. #### Example: If you want to remove the Authorization bearer token from your requests, simply add "Authorization" to the list of keys. Network log filters ### Set filter with code It's also possible to set the network log filters by code. ```javascript theme={null} // Manually set the network logs filters cordova.plugins.GleapPlugin.setNetworkLogPropsToIgnore([ "api-key", "user.password", "...", ]); ``` ## Blacklisting URLs It is possible to blacklist URLs or parts of URLs. If a network request matches one of the entries in the blacklist, the network request won't be included in the network logs. To add a new entry to the blacklist, simply navigate to your project in the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now click on `Developer options` and add the desired URLs. ### Set blacklist with code It's also possible to set the network log blacklist by code. ```javascript theme={null} // Manually set the network logs blacklist cordova.plugins.GleapPlugin.setNetworkLogsBlacklist([ "https://api.gleap.io", "...", ]); ``` # Prefill the widget form Source: https://docs.gleap.io/documentation/cordova/prefill-form-data In some situations you might want to prefill some fields for the user. This can be achieved by the following method. ```js theme={null} cordova.plugins.GleapPlugin.preFillForm({ description: "This text will be prefilled.", errordescription: "This text will be prefilled as well.", someformidentifier: "This text will also be prefilled.", }); ``` You need to pass a key value pair to the `preFillMethod`. The key is the form identifier, which can be found under the 'Advanced' section of a question. (see screenshot for an example) Form identifier # Release notes & news Source: https://docs.gleap.io/documentation/cordova/release-notes-and-news Gleap allows you to share release notes & news articles with your customers. Release notes and news for your app or website You can send release notes & news directly within the Gleap Dashboard. Once sent, the user gets notified when he starts his next session. ## Open the news section by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} cordova.plugins.GleapPlugin.openNews(false); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # Surveys Source: https://docs.gleap.io/documentation/cordova/surveys Gleap allows you to create micro surveys to be run directly in your Gleap widget. We offer templates for some of the most common survey types, such as NPS scores, product market fit or product satisfaction. ## Sending surveys with triggers Usually customers use triggers to send surveys. Example use cases for that include: * Sending surveys after a certain amount of time * Sending a survey on a certain page * Sending a survey after a specific event happened * ... In order to get started with survey triggers, you need to start tracking events. Once an event has been tracked, you can use it as trigger in the survey options. You can find more information about tracking events [here](./track-events). Gleap survey triggers ## Manually sending surveys You can also manually send surveys to your users. For this you only need to call the following method: ```javascript theme={null} cordova.plugins.GleapPlugin.showSurvey("survey_id", "survey"); ``` The first parameter is the survey id, the second parameter is the format of the survey. The format can be either `survey` (default: card style survey) or `survey_full` (full screen survey). Please note that the Gleap SDK needs to be fully initialized to be able to show a survey. # Track events Source: https://docs.gleap.io/documentation/cordova/track-events Gleap custom events allow you to log events at certain key positions within your application. This is super useful to get an even better understanding of what's happening within an application. Custom events do have a name and can contain event specific data as well. ## Track an event The following sample logs an event with the name "User signed in". ```javascript theme={null} cordova.plugins.GleapPlugin.trackEvent("User signed in"); ``` ## Track an event with attached data It's possible to attach data to custom events. The data can be viewed later in the respective bug report. ```javascript theme={null} cordova.plugins.GleapPlugin.trackEvent("User signed in", { userId: 1242, name: "Isabella", skillLevel: "🤩", }); ``` Your events will appear in the activity log of the bug report. # Track pages Source: https://docs.gleap.io/documentation/cordova/track-pages Automatic page tracking is not available for ReactNative due to platform limitations. We highly encourage you to still track pages with the following helper method. ## Track a page ```javascript theme={null} cordova.plugins.GleapPlugin.trackPage("HomePage"); ``` You will be able to use the tracked pages as triggers in outbound messages as well as breadcrumbs for debugging. # Translations Source: https://docs.gleap.io/documentation/cordova/translations Gleap was built for people around the world and offers translations for many languages by default. If we are missing a language or translation, you can simply add an additional language yourself in our visual widget configurator. Gleap automatically picks the device language as default language. If the device language is not available it will switch to English as a fallback. In some situations you might want to overwrite the device language with a custom language. This can be achieved with the following method. ### Overwrite the default language ```js theme={null} // 2 digit ISO code cordova.plugins.GleapPlugin.setLanguage("es"); // 5 digit ISO code with lang - country cordova.plugins.GleapPlugin.setLanguage("en-US"); ``` Available default languages are: en, de, fr, it, es, cz, nl. You can add custom translations in the Gleap dashboard. # User identity Source: https://docs.gleap.io/documentation/cordova/user-identity The Gleap Identify call lets you tie a user to their feedback items. It includes a unique User ID and optional meta information such as their email and name. ### Identify your users To effectively manage your contacts, we advise using `cordova.plugins.GleapPlugin.identify()` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `cordova.plugins.GleapPlugin.updateContact()`. This method allows for seamless real-time updates to contact details. Identify your user by calling the following method. ```javascript theme={null} cordova.plugins.GleapPlugin.identify("user_ID", { name: "Franz", email: "franz@gleap.io", phone: "+1 (902) 123123", value: 199.95, customData: { plan: "Pro plan", company: "ACME inc.", }, }); ``` When transmitting custom data, only primitive numeric and string values are supported for later use in segment filters. Please note that you can send only 35 custom data keys with an identify call. We currently only allow JSON strings, numbers and boolean values as custom data. Gleap defaults to guest sessions when feedback items get reported without calling the identify method first. All feedback items of an existing guest session will be merged with the user session once you've identified it. ### Enforce identity verification Enforce identity verification to prevent third parties from impersonating logged-in users. [Learn how to generate the user hash](../guides/enforce-identity-verification) ```js theme={null} cordova.plugins.GleapPlugin.identify( "user_ID", { name: "Franz", email: "franz@gleap.io", phone: "+1 (902) 123123", value: 199.95, customData: { plan: "Pro plan", company: "ACME inc.", }, }, "GENERATED_USER_HASH" ); ``` [Click here](../guides/enforce-identity-verification.mdx) to learn how to generate the user hash. ### Update contact properties To effectively manage your contacts, we advise using `cordova.plugins.GleapPlugin.identify()` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `cordova.plugins.GleapPlugin.updateContact()`. This method allows for seamless real-time updates to contact details. ```javascript theme={null} cordova.plugins.GleapPlugin.updateContact({ name: "Franz", value: 199.95, }); ``` The updateContact method takes in the same contact parameters as the identify method. Partial updates are possible. ```javascript theme={null} cordova.plugins.GleapPlugin.updateContact({ name: "Franz", email: "franz@gleap.io", phone: "+1 (902) 123123", value: 199.95, customData: { plan: "Pro plan", company: "ACME inc.", }, }); ``` ### Clear the identity on logout We recommend to clear the identity once the user logs out. Clearing the identity will automatically detach the current session and create a new guest session. ```js theme={null} cordova.plugins.GleapPlugin.clearIdentity(); ``` ### Get the identification status of a user With the following method, you can get the status of the current user identity. ```js theme={null} cordova.plugins.GleapPlugin.isUserIdentified((status) => { console.log(status); }); ``` ### Get the current user identity With the following method, you can get the current user identity. ```js theme={null} cordova.plugins.GleapPlugin.getIdentity((userIdentity) => { console.log(userIdentity); }); ``` # Widget control Source: https://docs.gleap.io/documentation/cordova/widget-control In some situations you might want to take full control over showing or hiding the Gleap widget. This can be achieved with the following methods. ### Open the Gleap widget ```javascript theme={null} cordova.plugins.GleapPlugin.open(); ``` ### Close the Gleap widget ```javascript theme={null} cordova.plugins.GleapPlugin.close(); ``` ### Widget open status It's possible to request the widget open status with the following method. ```javascript theme={null} const isOpened = cordova.plugins.GleapPlugin.isOpened(); ``` # Introducing Source: https://docs.gleap.io/documentation/flutter/README The Gleap SDK for Flutter is the easiest way to integrate Gleap into your apps. Communicate with your users directly and build better software by discovering their everyday pain points. Gleap is your all-in-one customer feedback tool for apps and websites. For the SDK to work, you need an API key, which you can get for free at [app.gleap.io](https://app.gleap.io). #### Supported platforms | ✅ iOS | ✅ Android | ✅ Web | | ----- | --------- | ----- | ## 🏗 Installation Open a terminal window and navigate to the root folder of your iOS project. ### Install the Gleap SDK #### Run this command to add Gleap to your dependencies: ``` flutter pub add gleap_sdk ``` #### Flutter v2 Support If you are using Flutter \< v3, please import the gleap\_sdk as shown below: ```dart theme={null} dependencies: gleap_sdk: git: url: https://github.com/GleapSDK/Flutter-SDK.git ref: flutter-v2 ``` ### iOS installation Navigate to your iOS project folder within the terminal and update your cocoapods by running: ```js theme={null} pod install ``` ### Android installation Android should be already good to go. If theres a version conflict pls add the following to your android manifest: ``` ... ``` **Important**: Always have a look at your minSdkVersion on android and your minimum target version on iOS to keep them on the same minimum version gleap needs. Do not set `android:hardwareAccelerated="false"` at the application level in your `AndroidManifest.xml`. This can cause issues with the Gleap SDK on Android. If you need to disable hardware acceleration, consider applying it only to specific activities instead. ### Web installation Navigate to your web project folder and insert the following snippet as first element within the head tag of your index.html ```js theme={null} ``` Please note that you must need to run `flutter clean` and `flutter pub get` after adding the Gleap script to your index.html file. ### Configure the SDK The last step is to initialize & configure the Gleap SDK by adding the following code. If you want to add the Gleap SDK in your main.dart make sure to call `WidgetsFlutterBinding.ensureInitialized();` before you initialize the Gleap SDK. ```dart theme={null} Gleap.initialize(token: 'YOUR_API_KEY'); ``` Congratulations 🎉 You are all set 👋 ## Required permissions (Android) In order to use the image picker for attachments, add the following permissions to your `AndroidManifest.xml`. ``` ``` The following permissions are needed to enable audio recordings. ``` ``` ## Required permissions (iOS) In order to use the image picker for attachments, add the following permissions to your `Info.plist`. ``` NSPhotoLibraryUsageDescription We need access to your photo library to allow you to select an image. NSCameraUsageDescription We need access to your camera to take photos. ``` The following permissions are needed to enable audio recordings. ``` NSMicrophoneUsageDescription We need access to your microphone to record audio with videos. ``` ## 🤝 Need help? We are here to help! [hello@gleap.io](mailto:hello@gleap.io) # Frontend tools Source: https://docs.gleap.io/documentation/flutter/aitools Frontend tools let your AI agent execute actions directly inside your app — initiating a transfer, resetting a password, cancelling an order, etc. Tools are defined on your AI agent in the Gleap dashboard (**AI agent > Tools > Frontend tool**) — name, description, parameters and execution mode all live there. Your app only registers a handler that executes the tool. Learn how to set up Frontend tools in our [help center article](https://help.gleap.io/en/articles/221-frontend-tools-let-the-ai-run-actions-in-your-app). ## Register a tool handler Register the handler for a dashboard-defined Frontend tool. Use the tool's runtime name shown in the tool editor. ```dart theme={null} Gleap.registerAgentTool( name: 'send-money', handler: (params) async { final amount = params['amount']; final contact = params['contact']; // Run your own logic here. // Return a string or JSON — the AI waits for this response. return 'The transfer was initiated. The user must confirm it in the banking app.'; }, ); ``` **Handler contract** * The handler receives the parameters configured in the dashboard as a map, filled with the values the AI collected. * Return a `String` or a JSON-encodable object (objects are stringified). The result is sent back to the AI, which uses it to reply. * Async handlers are fully supported — the AI waits for the returned future. * Thrown errors are caught and reported to the AI automatically. * If no handler is registered for a tool, the AI is informed so it can respond accordingly. * Works on Android, iOS and Web. ## Execution modes Set per tool in the dashboard: * `Auto` — the handler runs immediately when the AI calls the tool. * `Ask before final execution` — the AI adds a confirmation button to its reply; the handler only runs after the user confirms. ## Migrating from `setAiTools` `Gleap.setAiTools(tools: ...)` and the `AITool` / `AIToolParams` classes have been removed. Tools defined via `setAiTools` could only return a static response to the AI — Frontend tools execute real code and return live results. Define your tools on the AI agent in the dashboard and register their handlers via `Gleap.registerAgentTool(name:, handler:)` instead. The `toolExecution` listener remains available. # Audio recording Source: https://docs.gleap.io/documentation/flutter/audio-recording Available starting from version 14.2.0. Gleap allows users to record audio messages when chatting with support through our Flutter SDK. This is a great way to collect feedback from users. ## iOS setup In order for audio recording to work for iOS, you need to add the following key to your `Info.plist` file: ```xml theme={null} NSMicrophoneUsageDescription We need access to the microphone to record audio messages. ``` This key is required by iOS to allow the app to use the microphone. ## Android setup In order for audio recording to work for Android, you need to add the following keys to your `AndroidManifest.xml` file: ```xml theme={null} ``` This key is required by Android to allow the app to use the microphone. ## Enable the audio recording feature To enable the audio recording feature, navigate to `AI chatbot` -> `Settings` and toggle the `Allow audio messages` switch. # Checklists Source: https://docs.gleap.io/documentation/flutter/checklists Dive into a completely refreshed onboarding experience that will guide your users with gusto. The new checklist feature not only ensures your users are thoroughly onboarded but also keeps them deeply engaged. All of this is neatly packed inside our Gleap widget! ## Open the checklists overview Open the checklists overview with the method below. ```js theme={null} await Gleap.openChecklists(showBackButton: true); ``` ## Manually start a checklist Checklists can be sent either through trigger rules or manually with the method below. ```js theme={null} await Gleap.startChecklist(outboundId: "outboundId", showBackButton: true); ``` You can find the outboundId within the checklist editor. Please note that SDK version 12.1.0 or higher is required to send checklists. # Console logs Source: https://docs.gleap.io/documentation/flutter/console-logs The Gleap iOS SDK collects console logs for the `Release` profile by default. Further more you can make use of our custom logs, which offer more control over the logs. ## Default console logs Console logs are enabled by default on `Release` profile builds. In debug mode, console logs are disabled by default. ### Enable console logs in debug mode You can enable console logs in debug mode by calling the following method. Make sure to call this method `BEFORE` initializing the Gleap SDK. ```dart theme={null} Gleap.enableDebugConsoleLog(); ``` Please note that this can lead to freezing or crashing applications, depending on what 3rd party libraries you have installed. If you encounter an app freeze with this option enabled, please disable it again or remove 3rd parties, that also rewire the console logs (like Firebase Crashlytics or Sentry). ### Disable default console logs It is possible to disable the default collection of console logs by calling the following method prior to the initialization of Gleap. ```dart theme={null} Gleap.disableConsoleLog(); ``` ## Custom logs Custom logs allow you to create logs in the Gleap activity log. There are three severnity types available for logs: `ERROR`, `WARNING` and `INFO`. ```dart theme={null} Gleap.log(message: 'message'); ``` By default logs will be created with the severnity `INFO`. Use the following method to explicitly set the severnity. ```dart theme={null} Gleap.log(message: 'error message', logLevel: LogLevel.ERROR); ``` # Conversations Source: https://docs.gleap.io/documentation/flutter/conversations Conversations ## Start a new conversation You can manually start a new conversation with the following method: ```javascript theme={null} Gleap.startConversation(showBackButton: true); ``` Open the conversation history If you'd like to manually show the conversation history of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openConversations(showBackButton: true); ``` # Custom actions Source: https://docs.gleap.io/documentation/flutter/custom-actions We know that the built in actions (Bug Reporting, Feature Requests, Ratings & Contact Us) might not be enough for certain use cases. For these situations we offer custom actions, which allow you to start any custom action by code. ## Configure a custom action The first step with custom actions is to open the visual widget configurator and select **"Custom action"** as action type. Now you need to **set a name for your custom action**. Choose any name you like (it's however important that this name matches the name you check in the next step). Setup custom actions in the Gleap dashboard. ## Custom action callback Once you've set a custom action in the Gleap dashboard, it will be called automatically on selection through the user. In order to perform custom code, simply register the action to receive the custom action events. ### Add & implement the Gleap custom action The following code sample shows how to register a custom action. ```dart theme={null} Gleap.registerListener( actionName: '{custom-action-name}', callbackHandler: (dynamic actionName) { // Do something with the actionName }, ); ``` The **actionName** is defined by you in the visual widget configurator on the Gleap dashboard. # Custom data Source: https://docs.gleap.io/documentation/flutter/custom-data ## Add custom data In many situations you may want to attach custom data to feedback items in order to better understand the context. You can add custom data incrementally or all at once. Any simple JSON object can be attached. ```dart theme={null} Gleap.attachCustomData(customData: {'user': 'Franzi'}); ``` If you want to attach custom data incrementally, you can do so with the `setCustomData` method. ```dart theme={null} Gleap.setCustomData(key: 'value', value: 'Franzi'); ``` ## Remove custom data Remove custom data key value pairs by calling the following method. ```dart theme={null} Gleap.removeCustomDataForKey(key: 'value'); ``` ## Clear all custom data It's possible to clear all attached custom data by calling the following method. ```dart theme={null} Gleap.clearCustomData(); ``` # Callbacks Source: https://docs.gleap.io/documentation/flutter/events Set callbacks to different actions to get notified on certain state changes of the Gleap widget. This enables you to create an even deeper integration with Gleap. ```dart theme={null} Gleap.registerListener( actionName: 'feedbackFlowStarted', callbackHandler: (dynamic flow) { // Do something with the flow }, ); ``` ```dart theme={null} Gleap.registerListener( actionName: 'initialized', callbackHandler: (_) { // Do something when Gleap is initialized }, ); ``` ```dart theme={null} Gleap.registerListener( actionName: 'notificationCountUpdated', callbackHandler: (dynamic count) { // Do something with the count }, ); ``` ```dart theme={null} Gleap.registerListener( actionName: 'feedbackSent', callbackHandler: (_) { // Do something }, ); ``` ```dart theme={null} Gleap.registerListener( actionName: 'feedbackSendingFailed', callbackHandler: (_) { // Do something }, ); ``` ```dart theme={null} Gleap.registerListener( actionName: 'widgetOpened', callbackHandler: (_) { // Do something }, ); ``` ```dart theme={null} Gleap.registerListener( actionName: 'widgetClosed', callbackHandler: (_) { // Do something }, ); ``` # Feature requests Source: https://docs.gleap.io/documentation/flutter/feature-requests The new Gleap widget offers a feature request view allowing users to view, upvote & comment more easily on feature requests. Release notes and news for your app or website You can enable the feature requests view directly within the Gleap Dashboard or show it by code. ## Open the feature requests app by code If you'd like to manually show the feature requests app of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} await Gleap.openFeatureRequests(showBackButton: true); ``` # Feedback button Source: https://docs.gleap.io/documentation/flutter/feedback-button In some situations you might want to take full control over the feedback button. In order to show or hide the feedback button, you can simply use the following methods. ### Show the feedback button ```javascript theme={null} Gleap.showFeedbackButton(true); ``` ### Hide the feedback button ```javascript theme={null} Gleap.showFeedbackButton(false); ``` Gleap feedback button with live chat bubble # Forms Source: https://docs.gleap.io/documentation/flutter/feedback-flows Gleap forms are a traditional, straightforward approach for user data input. They offer a simple, efficient method for users to provide specific information or feedback. Forms are particularly useful when detailed user input is essential, allowing for a clear, direct way of data collection without the dynamic steps involved in workflows. This makes forms a reliable option for scenarios where straightforward, user-provided data is key. If you want to manually show a form, simply call one of the following methods. ### Bug reporting form The bug reporting form is the default form for bug reports and allows users to mark bugs and add a description as well as their email address. ```javascript theme={null} // Starts a classic bug reporting form. Gleap.startClassicForm(formId: "bugreporting"); ``` The first parameter determines the flow that should be started. The second parameter allows you to pass the `showBackButton` form option. ### Feature request form This form is great if you want to collect feature requests. You can also embed your Gleap roadmap and share it with your users to have them vote on requests. ```javascript theme={null} // Starts a classic feature request form. Gleap.startClassicForm(formId: "featurerequests"); ``` ### Custom forms Gleap also allows you to configure custom forms. This is especially handy if our default forms don't fully cover your use cases. Visit our dashboard for more information on custom forms. Classic forms ```javascript theme={null} // Starts a classic form with the CUSTOM_FORM_KEY as key. Gleap.startClassicForm(formId: "CUSTOM_FORM_KEY"); ``` # Help center Source: https://docs.gleap.io/documentation/flutter/helpcenter Happier customers, fewer support questions. What’s not to like? Make it easy for users to access information with our help center articles. Release notes and news for your app or website **Show help center articles** directly within the **Gleap widget**, to offer customers the help they need at the right place & time. ## Open the help center by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} await Gleap.openHelpCenter(showBackButton: true); ``` ## Open a help center article by code If you'd like to open a help center article directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} await Gleap.openHelpCenterArticle(articleId: "articleId", showBackButton: true); ``` *The first parameter **articleId** can be found at the bottom of your article editor in the **Share this article** banner.* ## Open a help center collection by code If you'd like to open a collection directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} await Gleap.openHelpCenterCollection(collectionId: "collectionId", showBackButton: false); ``` *The first parameter **collectionId** can be found at the bottom of collection in the **Share this collection** banner.* ## Search your help center If you'd like to search for help articles, you can do so by calling the following method: ```javascript theme={null} await Gleap.searchHelpCenter(term: "Search term", showBackButton: true); ``` # In-app notifications Source: https://docs.gleap.io/documentation/flutter/in-app-push-notifications With Gleap, in-app notifications appear directly within the app when a new message is sent to a customer who has the app open. The same applies to news updates. We also support push notification. Please see the push notifications documentation for more information on it. ## Disable in-app notifications The following method allows you to disable the in app notifications. ```js theme={null} Gleap.setDisableInAppNotifications(true); ``` ## Notification container offset You can adjust the position of the in-app notification container by setting an offset in pixels: ```dart theme={null} Gleap.setNotificationContainerOffset(x: 10.0, y: 20.0); ``` * **x** – Horizontal offset in pixels (positive values move the container to the right). * **y** – Vertical offset in pixels (positive values move the container down). # Network logs Source: https://docs.gleap.io/documentation/flutter/network-logs Gleap allows you to monitor all network requests for a better understanding of what's happening within your apps. ### **Enable network logs** Simply enable the network logs within the visual widget configurator and add the Flutter Gleap Interceptor to your http client. ### **Configure network logs in Flutter** We support network logging for the packages [Http](https://pub.dev/packages/http) and [Dio](https://pub.dev/packages/dio). For details on how to enable network logging for these packages, check the [Gleap Http Interceptor](https://pub.dev/packages/gleap_http_interceptor) and the [Gleap Dio Interceptor](https://pub.dev/packages/gleap_dio_interceptor) packages. ### **Gleap Http Interceptor** Simple add the [Gleap Http Interceptor](https://pub.dev/packages/gleap_http_interceptor) package to your dependencies and attach the `GleapHttpInterceptor()` to your http client. ```dart theme={null} Client client = InterceptedClient.build(interceptors: [ GleapHttpInterceptor(), ]); client.get(Uri.parse("https://example.com")); ``` ### **Gleap Dio Interceptor** Simple add the [Gleap Dio Interceptor](https://pub.dev/packages/gleap_dio_interceptor) package to your dependencies and attach the `GleapDioInterceptor()` to your http client. ```dart theme={null} Dio dio = Dio(); dio.interceptors.add(GleapDioInterceptor()); dio.get("https://example.com") ``` ## Filtering network logs Gleap allows you to strip off specific key/value pairs from network logs. This empowers you to easily remove sensitive data like `tokens, passwords` or `usernames`. ### How does it work? Log in to the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now enable the `network log filters` option (within the advanced options tab). Once the option is enabled, you can add multiple keys to the array bellow, which should be excluded. All keys, which you add to the exclusion list, will be loaded together with the widget configuration. Before sending a feedback item to our backend, the client SDK will loop through all network requests and stripe off all matching key/value pairs from the `request headers`, `header-payload` (if it's a JSON) and `response body` (if it's a JSON). This ensures that sensitive information will never even leave the client application. #### Example: If you want to remove the Authorization bearer token from your requests, simply add "Authorization" to the list of keys. Network log filters ### Set filter with code It's also possible to set the network log filters by code. ```javascript theme={null} // Manually set the network logs filters Gleap.setNetworkLogPropsToIgnore( blacklist: ["api-key", "user.password", "..."] ) ``` ## Blacklisting URLs It is possible to blacklist URLs or parts of URLs. If a network request matches one of the entries in the blacklist, the network request won't be included in the network logs. To add a new entry to the blacklist, simply navigate to your project in the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now click on `Developer options` and add the desired URLs. ### Set blacklist with code It's also possible to set the network log blacklist by code. ```javascript theme={null} // Manually set the network logs blacklist Gleap.setNetworkLogsBlacklist( networkLogPropsToIgnore: ["https://api.gleap.io", "..."] ) ``` # Prefill the widget form Source: https://docs.gleap.io/documentation/flutter/prefill-form-data In some situations you might want to prefill some fields for the user. This can be achieved by the following method. ```dart theme={null} Gleap.preFillForm( formData: { 'description': 'This text will be prefilled.', 'errordescription': 'This text will be prefilled as well.', 'someformidentifier': 'This text will also be prefilled.', }, ); ``` You need to pass a key value pair to the `preFillMethod`. The key is the form identifier, which can be found under the 'Advanced' section of a question. (see screenshot for an example) Form identifier # Push notifications Source: https://docs.gleap.io/documentation/flutter/push-notifications Stay connected with your customers by utilizing push notifications to alert them of new chat messages, release notes, and news articles. This will deepen engagement and foster stronger relationships. Gleap supports Firebase Cloud Messaging to send push notifications to users. ## Setup Firebase Cloud Messaging To make use of Gleap Push Notifications you must add the Firebase Cloud Messaging service to your app or website. Learn how to get started with FCM here. ## Getting your Firebase Cloud Messaging Token Open your project in Firebase and open the project settings. Click on "Cloud Messaging" and, if it is not already enabled, activate the Firebase Cloud Messaging API (V1). Gleap Firebase Setup Proceed to the "Service Accounts" section and generate a new private key, which will automatically create a file named like `serviceAccountKey.json`. Gleap Firebase Setup Next, open the project settings in Gleap, select "Push Notifications", and upload the `serviceAccountKey.json` file. Finally, save your configuration. Gleap Push Notifications Setup ## Subscribe to the Gleap user topic The last step to complete the push notification setup is to subscribe to the user topic, which Gleap will send the push notifications to. In order to do so, you will need to register the register & unregister push message topic callbacks. ```dart theme={null} // Find more information here: // https://pub.dev/packages/firebase_messaging Gleap.registerPushMessageGroup(callbackHandler: (String topic) { FirebaseMessaging.instance.subscribeToTopic(topic); }); Gleap.unregisterPushMessageGroup(callbackHandler: (String topic) { FirebaseMessaging.instance.unsubscribeFromTopic(topic); }); ``` Please note that these callbacks should be called before initializing Gleap. ## Handle push-notifications click To handle push notifications, you will need to register a callback handler for the `onMessage`, `onMessageOpenedAppHandler` and `onBackgroundMessageHandler` callbacks. ```dart theme={null} static Future onMessageOpenedAppHandler(RemoteMessage message) async { if (message.data['sender'] == 'GLEAP') { Gleap.handlePushNotification(data: message.data); } } ``` That's it - build and run your app 🚀 ## Notification images When a changelog or news article with a featured image is sent as a push notification, Gleap includes the image in the FCM payload. * **Android** displays the image automatically when the notification arrives while your app is in the background — no setup required. * **iOS** requires a Notification Service Extension in your app to display the image. Follow the native setup in the [iOS push notification guide](/documentation/ios/push-notifications#notification-images) — the extension is added to the iOS project in Xcode and works unchanged in a Flutter app. # Release notes & news Source: https://docs.gleap.io/documentation/flutter/release-notes-and-news Gleap allows you to share release notes & news articles with your customers. Release notes and news for your app or website You can send release notes & news directly within the Gleap Dashboard. Once sent, the user gets notified when he starts his next session. ## Open the news section by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} await Gleap.openNews(showBackButton: true); ``` # Surveys Source: https://docs.gleap.io/documentation/flutter/surveys Gleap allows you to create micro surveys to be run directly in your Gleap widget. We offer templates for some of the most common survey types, such as NPS scores, product market fit or product satisfaction. ## Sending surveys with triggers Usually customers use triggers to send surveys. Example use cases for that include: * Sending surveys after a certain amount of time * Sending a survey on a certain page * Sending a survey after a specific event happened * ... In order to get started with survey triggers, you need to start tracking events. Once an event has been tracked, you can use it as trigger in the survey options. You can find more information about tracking events [here](./track-events). Gleap survey triggers ## Manually sending surveys You can also manually send surveys to your users. For this you only need to call the following method: ```js theme={null} Gleap.showSurvey(surveyId: '', format: SurveyFormat.SURVEY_FULL); ``` The first parameter is the survey id, the second parameter is the format of the survey. The format can be either `SurveyFormat.SURVEY` (default: card style survey) or `SurveyFormat.SURVEY_FULL` (full screen survey). Please note that the Gleap SDK needs to be fully initialized to be able to show a survey. ## Send surveys with URL parameters (Web SDK only) You can also send surveys with URL parameters. This is useful if you want to send surveys to specific users. For example, you can send a survey to a specific user by sending them a link like this: ``` https://yourapp.com/?gleap_survey=\{your-survey-id\}&gleap_survey_format=\{survey\} ``` Please replace \{your-survey-id} with your survey id and \{survey} with the survey format. The survey format can be either "survey" (default: card style survey) or "survey\_full" (full screen survey). The application that you use for sending surveys with URL parameters needs to have the Gleap SDK installed. # Tags Source: https://docs.gleap.io/documentation/flutter/tags Gleap allows you to set tags with every feedback item sent from the SDK. To set tags, simply pass an array of Strings to the `setTags` method of the SDK. ## Set tags Set tags to be sent with every feedback item. ```javascript theme={null} Gleap.setTags(["iOS", "Subscribed"]); ``` If you want to update or remove the tags, simply call the method with the updated string array. # Ticket attributes Source: https://docs.gleap.io/documentation/flutter/ticket-attributes Ticket custom data ## Set ticket attributes Ticket attributes can be set with the method below. If the user also provides data for an attribute (for example `description`), the user input will be prioritized. ```javascript theme={null} Gleap.setTicketAttribute(key: 'title', value: 'Developer title'); ``` **First param**: attribute key
**Second param**: value (string, boolean, string array or number are supported) Ticket attribute data will not be [pre-filled](reactnative/prefill-form-data.md) in forms. ## Finding the ticket attribute keys You can find or create all available ticket attributes for each ticket type in **Settings** > **Data attributes**. Ticket attribute ## Unset ticket attributes Ticket attributes can be unset with the method below. ```javascript theme={null} Gleap.unsetTicketAttribute(key: 'title'); ``` ## Clear all ticket attributes All ticket attributes can be cleared with the method below. ```javascript theme={null} Gleap.clearTicketAttributes(); ``` # Track events Source: https://docs.gleap.io/documentation/flutter/track-events Gleap custom events allow you to log events at certain key positions in your application. This is super useful to get an even better understanding of what's happening within an application. Custom events do have a name and can contain event specific data as well. ## Track an event The following sample logs an event with the name "User signed in". ```dart theme={null} Gleap.trackEvent(name: 'User signed in'); ``` ## Track an event with attached data It's possible to attach data to custom events. The data can be viewed later in the bug report. ```javascript theme={null} Gleap.trackEvent( name: 'User signed in', data: {'userId': 1242, 'name': 'Isabella'} ); ``` Your events will appear in the activity log of the bug report. # Track pages Source: https://docs.gleap.io/documentation/flutter/track-pages Automatic page tracking is not available for Flutter due to platform limitations. We highly encourage you to still track pages with the following helper method. ## Track a page ```dart theme={null} Gleap.trackPage(pageName: "HomePage"); ``` You will be able to use the tracked pages as triggers in outbound messages as well as breadcrumbs for debugging. # Translations Source: https://docs.gleap.io/documentation/flutter/translations Gleap was built for people around the world and offers translations for many languages by default. If we are missing a language or translation, you can simply add an additional language yourself in our visual widget configurator. Gleap automatically picks the device language as default language. If the device language is not available it will switch to English as a fallback. In some situations you might want to overwrite the device language with a custom language. This can be achieved with the following method. ### Overwrite the default language ```dart theme={null} Gleap.setLanguage(language: 'de'); ``` ```dart theme={null} // 5 digit ISO code with lang - country Gleap.setLanguage(language: 'en-US'); ``` Please use the `setLanguage` method only before the initialization of the Gleap SDK (before calling `Gleap.initialize()`) # User identity Source: https://docs.gleap.io/documentation/flutter/user-identity The Gleap identify call lets you tie a user to their feedback items. It includes a unique User ID and optional meta information such as email & name. ### Identify your users To effectively manage your contacts, we advise using `Gleap.identify()` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `Gleap.updateContact()`. This method allows for seamless real-time updates to contact details. Identify your user by calling the following method. ```dart theme={null} Gleap.identify( userId: '12345', userProperties: GleapUserProperty( name: 'Franz', email: 'franz@gleap.io', phone: '+1 (902) 123123', companyName: 'ACME inc.', companyId: '19283', plan: 'Pro plan', avatar: 'https://.../avatar.png', value: 199.95, customData: { 'key1': 'Test', 'key2': 'ACME', }, ), ); ``` When transmitting custom data, only primitive numeric and string values are supported for later use in segment filters. Please note that you can send only 35 custom data keys with an identify call. We currently only allow JSON strings, numbers and boolean values as custom data. Gleap defaults to guest sessions when feedback items get reported without calling the identify method first. All feedback items of an existing guest session are merged with the user session once you've identified it. ### Enforce identity verification Enforce identity verification to prevent third parties from impersonating logged-in users. [Learn how to generate the user hash](../guides/enforce-identity-verification) ```dart theme={null} Gleap.identify( userId: '12345', userProperties: GleapUserProperty( name: 'Franz', email: 'franz@gleap.io', phone: '+1 (902) 123123', companyName: 'ACME inc.', companyId: '19283', plan: 'Pro plan', value: 199.95, avatar: 'https://.../avatar.png', customData: { 'key1': 'Test', 'key2': 'ACME', }, ), userHash: 'GENERATED_USER_HASH' ); ``` ### Update contact properties To effectively manage your contacts, we advise using `Gleap.identify()` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `Gleap.updateContact()`. This method allows for seamless real-time updates to contact details. ```javascript theme={null} Gleap.updateContact( userProperties: GleapUserProperty( plan: 'Pro plan', value: 199.95, ), ); ``` The updateContact method takes in the same contact parameters as the identify method. Partial updates are possible. ```javascript theme={null} Gleap.updateContact( userProperties: GleapUserProperty( name: 'Franz', email: 'franz@gleap.io', phone: '+1 (902) 123123', companyName: 'ACME inc.', companyId: '19283', plan: 'Pro plan', value: 199.95, avatar: 'https://.../avatar.png', customData: { 'key1': 'Test', 'key2': 'ACME', }, ), ); ``` ### Clear the identity on logout We recommend to clear the identity once the user logs out. Clearing the identity will automatically detach the current session and create a new guest session. ```js theme={null} Gleap.clearIdentity(); ``` ### Get the identification status of a user With the following method, you can get the status of the current user identity. ```js theme={null} Gleap.isUserIdentified(); ``` ### Get the current user identity With the following method, you can get the current user identity. ```js theme={null} Gleap.getIdentity(); ``` # Widget control Source: https://docs.gleap.io/documentation/flutter/widget-control In some situations you might want to take full control over showing the Gleap widget. This can be achieved with the following method. ### Open the Gleap widget ```dart theme={null} Gleap.open(); ``` This method opens the Gleap widget and shows the feedback menu options. ### Close the Gleap widget ```dart theme={null} Gleap.close(); ``` This method closes the Gleap widget. ### Widget open status It's possible to request the widget open status with the following method. ```dart theme={null} Gleap.isOpened(); ``` # Introducing Source: https://docs.gleap.io/documentation/flutterflow/README The Gleap SDK for FlutterFlow is the easiest way to integrate Gleap into your apps. Communicate with your users directly and build better software by discovering their everyday pain points. Gleap is your all-in-one customer feedback tool for apps and websites. For the SDK to work, you need an API key, which you can get for free at [app.gleap.io](https://app.gleap.io). #### Supported platforms | ✅ iOS | ✅ Android | ✅ Web | | ----- | --------- | ----- | ### Installing the Gleap SDK 1. Navigate to the `Custom Code` section in FlutterFlow and create a new `Custom Action` called `gleapInitialize`. 2. Add the latest [Flutter Gleap SDK](https://pub.dev/packages/gleap_sdk) as a dependency, then refresh the code editor to load the pubspec dependencies. 3. Copy and paste the following code to initialize Gleap, replacing `'YOUR_API_KEY'` with your actual API key, and save the configuration: ```js theme={null} // Automatic FlutterFlow imports import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_util.dart'; import '/custom_code/actions/index.dart'; // Imports other custom actions import '/flutter_flow/custom_functions.dart'; // Imports custom functions import 'package:flutter/material.dart'; // Begin custom action code // DO NOT REMOVE OR MODIFY THE CODE ABOVE! import 'package:gleap_sdk/gleap_sdk.dart'; Future gleapInitialize() async { Gleap.initialize(token: 'YOUR_API_KEY'); } ``` FlutterFlow intialize custom code ### Web Installation For web support, go to `App Settings` > `Web Deployment`, and paste the following script into the `Custom Headers` section: ```js theme={null} ``` FlutterFlow web installation ### SDK Configuration To configure the SDK, navigate to `main.dart` under `Custom Files`, and add the newly created `gleapInitialize` function to the `Final Actions` section. Save the configuration. FlutterFlow configure the SDK ### Run your app Deploy and run your app to experience Gleap in action. FlutterFlow in action ### Utilizing the Gleap SDK You can utilize all the features provided by the Flutter Gleap SDK by creating custom actions for each method. For more information on configuration options, visit the [Flutter Gleap documentation](/flutter). FlutterFlow configuration options ### 🎉 You're All Set! Congratulations! Your Gleap integration is complete, and you're ready to collect valuable user feedback. ## 🤝 Need help? We are here to help! [hello@gleap.io](mailto:hello@gleap.io) # Enforce identity verification Source: https://docs.gleap.io/documentation/guides/enforce-identity-verification Enforce identity verification on all platforms to prevent third parties from impersonating logged-in users. Once enabled, Gleap will require you to pass the correct user hash in order to identify users. ## User hash generation To set up identity verification, you'll need to generate an HMAC on your server for each logged-in user and send it to Gleap. Please choose your server stack to show an example code for the user hash generation. ```js theme={null} const crypto = require('crypto'); const hmac = crypto.createHmac('sha256', 'YOUR-SECRET'); // secret key (keep it safe!) const userIdAsString = String(user.id); // convert user's id to string const userHash = hmac.update(userIdAsString).digest('hex'); // generate hash ``` ```rails theme={null} OpenSSL::HMAC.hexdigest( 'sha256', # hash function 'YOUR-SECRET', # secret key (keep safe!) current_user.id.to_s # user's id ) ``` ```py theme={null} import hmac import hashlib hmac.new( b'YOUR-SECRET', # secret key (keep it safe!) bytes(request.user.id, encoding='utf-8'), # user's id digestmod=hashlib.sha256 # hash function ).hexdigest() ``` ```php theme={null} $userHash = hash_hmac( 'sha256', // hash function $user->id, // user ID 'YOUR-SECRET' // secret key (keep it safe!) ); ``` Important: Gleap handles the userId as STRING, please make sure to convert the user ID to a string, before generating the hash. Keep your secret key safe! Never commit it directly to your client-side code, or anywhere a third party can find it. ## Indentify user with user hash After generating the user hash you need to send it to your client and pass it to the Gleap SDK. ```js theme={null} Gleap.identify("user_19283", { name: "Franz", email: "franz@gleap.io", }, "GENERATED_USER_HASH"); ``` ```objc theme={null} let userProperty = GleapUserProperty() userProperty.name = "Franz" userProperty.email = "franz@gleap.io" Gleap.identifyUser(with: "user_1234", andData: userProperty andUserHash: "GENERATED_USER_HASH") ``` ```java theme={null} GleapUserProperties userProperties = new GleapUserProperties(); userProperties.setEmail("franzi@gleap.io"); userProperties.setName("Franzi"); userProperties.setPhone("+1 (902) 123123"); userProperties.setValue(199.95); userProperties.setHash("GENERATED_USER_HASH"); Gleap.getInstancen().identifyUser("12334", userProperties); ``` ```js theme={null} Gleap.identifyWithUserHash('12334', { name: 'Franz', email: 'franz@gleap.io', }, 'GENERATED_USER_HASH'); ``` ```js theme={null} Gleap.identifyWithUserHash( userId: '12345', userProperties: GleapUserProperty(name: 'Franz', email: 'franz@gleap.io'), 'GENERATED_USER_HASH', ); ``` # Introducing Source: https://docs.gleap.io/documentation/ioniccapacitor/README The Gleap SDK for Ionic / Capacitor is the easiest way to integrate Gleap into your apps. Communicate with your users directly and build better software by discovering their everyday pain points. Gleap is your all-in-one customer feedback tool for apps and websites. For the SDK to work, you need an API key, which you can get for free at [app.gleap.io](https://app.gleap.io). ## 🏗 Installation Installing the Gleap SDK takes only a few seconds. Install the **Gleap** package via npm. ``` npm install capacitor-gleap-plugin ``` Sync your capacitor dependencies: ``` npx cap sync ``` *** Initialize the Gleap SDK by adding the following code to your index.js/.tsx file or main component. ```Ionic / Capacitor theme={null} import { Gleap } from 'capacitor-gleap-plugin'; // Please make sure to call this method only once! Gleap.initialize("ogWhNhuiZcGWrva5nlDS8l7a78OfaLlV"); ``` Install the **Gleap** package via npm. ``` npm install GleapSDK/Capacitor-SDK#capacitor-v4 --save ``` Sync your capacitor dependencies: ``` npx cap sync ``` *** Initialize the Gleap SDK by adding the following code to your index.js/.tsx file or main component. ```Ionic / Capacitor theme={null} import { Gleap } from 'capacitor-gleap-plugin'; // Please make sure to call this method only once! Gleap.initialize("ogWhNhuiZcGWrva5nlDS8l7a78OfaLlV"); ``` Install the **Gleap** package via npm. ``` npm install capacitor-gleap-plugin@8.2.3 ``` Sync your capacitor dependencies: ``` npx cap sync ``` *** Initialize the Gleap SDK by adding the following code to your index.js/.tsx file or main component. ```Ionic / Capacitor theme={null} import { Gleap } from 'capacitor-gleap-plugin'; // Please make sure to call this method only once! Gleap.initialize("ogWhNhuiZcGWrva5nlDS8l7a78OfaLlV"); ``` Congrats! You are now all set 🎉 Report your first bug by using the feedback button ## Required permissions (Android) In order to use the image picker for attachments, add the following permissions to your `AndroidManifest.xml`. ``` ``` The following permissions are needed to enable audio recordings. ``` ``` ## Required permissions (iOS) In order to use the image picker for attachments, add the following permissions to your `Info.plist`. ``` NSPhotoLibraryUsageDescription We need access to your photo library to allow you to select an image. NSCameraUsageDescription We need access to your camera to take photos. ``` The following permissions are needed to enable audio recordings. ``` NSMicrophoneUsageDescription We need access to your microphone to record audio with videos. ``` ## 🤝 Need help? We are here to help! [hello@gleap.io](mailto:hello@gleap.io) # Frontend tools Source: https://docs.gleap.io/documentation/ioniccapacitor/aitools *Tags*: Ionic, Capacitor Frontend tools let your AI agent execute actions directly inside your app — initiating a transfer, resetting a password, cancelling an order, etc. Tools are defined on your AI agent in the Gleap dashboard (**AI agent > Tools > Frontend tool**) — name, description, parameters and execution mode all live there. Your app only registers a handler that executes the tool. Learn how to set up Frontend tools in our [help center article](https://help.gleap.io/en/articles/221-frontend-tools-let-the-ai-run-actions-in-your-app). ## Register a tool handler Register the handler for a dashboard-defined Frontend tool with the `registerAgentTool` helper. Use the tool's runtime name shown in the tool editor. ```js theme={null} import { registerAgentTool } from "capacitor-gleap-plugin"; await registerAgentTool("send-money", async ({ amount, contact }) => { // Run your own logic here. // Return a string or JSON — the AI waits for this response. return "The transfer was initiated. The user must confirm it in the banking app."; }); ``` **Handler contract** * The handler receives the parameters configured in the dashboard, filled with the values the AI collected. * Return a string or a JSON-serializable object (objects are stringified). The result is sent back to the AI, which uses it to reply. * Async handlers are fully supported — the AI waits for the returned promise. * Thrown errors are caught and reported to the AI automatically. * If no handler is registered for a tool, the AI is informed so it can respond accordingly. * Works on iOS, Android and Web. ## Execution modes Set per tool in the dashboard: * `Auto` — the handler runs immediately when the AI calls the tool. * `Ask before final execution` — the AI adds a confirmation button to its reply; the handler only runs after the user confirms. ## Migrating from `setAiTools` `Gleap.setAiTools({ tools })` has been removed. Tools defined via `setAiTools` could only return a static response to the AI — Frontend tools execute real code and return live results. Define your tools on the AI agent in the dashboard and register their handlers via the `registerAgentTool(name, handler)` helper instead. The `tool-execution` event on `setEventCallback` remains available. # Audio recording Source: https://docs.gleap.io/documentation/ioniccapacitor/audio-recording Available starting from version 14.2.0. Gleap allows users to record audio messages when chatting with support through our Ionic /Capacitor SDK. This is a great way to collect feedback from users. ## iOS setup In order for audio recording to work for iOS, you need to add the following key to your `Info.plist` file: ```xml theme={null} NSMicrophoneUsageDescription We need access to the microphone to record audio messages. ``` This key is required by iOS to allow the app to use the microphone. ## Android setup In order for audio recording to work for Android, you need to add the following keys to your `AndroidManifest.xml` file: ```xml theme={null} ``` This key is required by Android to allow the app to use the microphone. ## Enable the audio recording feature To enable the audio recording feature, navigate to `AI chatbot` -> `Settings` and toggle the `Allow audio messages` switch. # Checklists Source: https://docs.gleap.io/documentation/ioniccapacitor/checklists Dive into a completely refreshed onboarding experience that will guide your users with gusto. The new checklist feature not only ensures your users are thoroughly onboarded but also keeps them deeply engaged. All of this is neatly packed inside our Gleap widget! ## Open the checklists overview Open the checklists overview with the method below. ```js theme={null} Gleap.openChecklists({ showBackButton: true, }); ``` ## Manually start a checklist Checklists can be sent either through trigger rules or manually with the method below. ```js theme={null} Gleap.startChecklist({ outboundId: "outboundId", showBackButton: true, }); ``` You can find the outboundId within the checklist editor. Please note that SDK version 12.1.0 or higher is required to send checklists. # Console logs Source: https://docs.gleap.io/documentation/ioniccapacitor/console-logs The Gleap SDK collects console logs by default. Further more you can make use of our custom logs, which offer more control over the logs. ## Disable default console logs It is possible to disable the default collection of console logs by calling the following method prior to the initialization of Gleap. ``` Gleap.disableConsoleLogOverwrite(); ``` ## Custom logs Custom logs allow you to create logs in the Gleap activity log. There are three severnity types available for logs: `ERROR`, `WARNING` and `INFO`. ``` Gleap.log({ message: "This is a test custom log." }); ``` By default logs will be created with the severnity `INFO`. Use the following method to explicitly set the severnity. ``` Gleap.log({ message: "This is a test custom log WARNING.", logLevel: "WARNING" }); ``` # Conversations Source: https://docs.gleap.io/documentation/ioniccapacitor/conversations Conversations ## Start a new conversation You can manually start a new conversation with the following method: ```javascript theme={null} Gleap.startConversation(true); ``` Open the conversation history If you'd like to manually show the conversation history of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openConversations(); ``` # Custom actions Source: https://docs.gleap.io/documentation/ioniccapacitor/custom-actions We know that the built in actions (Bug Reporting, Feature Requests, Ratings & Contact Us) might not be enough for certain use cases. For these situations we offer custom actions, which allow you to start any custom action by code. ## Configure a custom action The first step with custom actions is to open the visual widget configurator and select **"Custom action"** as action type. Now you need to **set a name for your custom action**. Choose any name you like (it's however important that this name matches the name you check in the next step). Setup custom actions in the Gleap dashboard. ## Custom action callback Once you set a custom action in the Gleap dashboard, it will be called automatically on selection through the user. In order to perform custom code, simply listen for custom actions by using the `registerCustomAction` method. If you use multiple custom actions, we suggest you check the triggered custom action's name in order to find out which custom action got triggered. ```javascript theme={null} Gleap.setEventCallback((message, err) => { const { name, data } = message; if (name === "custom-action-called") { console.log(data); } }); ``` The **custom action name** is defined by you in the visual widget configurator. # Custom data Source: https://docs.gleap.io/documentation/ioniccapacitor/custom-data ## Add custom data In many situations you may want to attach custom data to feedback items in order to better understand the context. You can add custom data incrementally or all at once. Any simple JSON object can be attached. ```javascript theme={null} Gleap.attachCustomData({ data: { test1: "Battle", data2: "Unicorn", }, }); ``` ## Append custom data If you want to attach custom data incrementally you can do so with the `setCustomData` method. ```javascript theme={null} Gleap.setCustomData({ key: "email", value: "lukas@bugbattle.io", }); ``` ## Remove custom data Remove custom data key value pairs by calling the following method. ```javascript theme={null} Gleap.removeCustomData({ key: "email", }); ``` ## Clear all custom data It's possible to clear all attached custom data by calling the following method. ```javascript theme={null} Gleap.clearCustomData(); ``` # Callbacks Source: https://docs.gleap.io/documentation/ioniccapacitor/events Use the following callbacks to get notified on certain state changes of the Gleap widget. This enables you to create an even deeper integration with Gleap. ```javascript theme={null} Gleap.setEventCallback((message, err) => { const { name, data } = message; if (name === "open") { // Widget openend } if (name === "close") { // Widget openend } if (name === "notification-count-updated") { // Notification count changed console.log("Unread notifications", data); } if (name === "feedback-sent") { // Feedback sent console.log("Form data: ", data); } if (name === "outbound-sent") { // Feedback sent console.log("Outbound data: ", data); } if (name === "flow-started") { // Flow started console.log("Flow: ", data); } if (name === "error-while-sending") { // Error while sending } if (name === "custom-action-called") { // Custom action called console.log("Custom action: ", data); } }); ``` # Feature requests Source: https://docs.gleap.io/documentation/ioniccapacitor/feature-requests The new Gleap widget offers a feature request view allowing users to view, upvote & comment more easily on feature requests. Release notes and news for your app or website You can enable the feature requests view directly within the Gleap Dashboard or show it by code. ## Open the feature requests app by code If you'd like to manually show the feature requests app of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openFeatureRequests({ showBackButton: true, }); ``` # Feedback button Source: https://docs.gleap.io/documentation/ioniccapacitor/feedback-button In some situations you might want to take full control over the feedback button. In order to show or hide the feedback button, you can simply use the following methods. ### Show the feedback button ```javascript theme={null} Gleap.showFeedbackButton({ show: true, }); ``` ### Hide the feedback button ```javascript theme={null} Gleap.showFeedbackButton({ show: false, }); ``` Gleap feedback button with live chat bubble # Forms Source: https://docs.gleap.io/documentation/ioniccapacitor/feedback-flows Gleap forms are a traditional, straightforward approach for user data input. They offer a simple, efficient method for users to provide specific information or feedback. Forms are particularly useful when detailed user input is essential, allowing for a clear, direct way of data collection without the dynamic steps involved in workflows. This makes forms a reliable option for scenarios where straightforward, user-provided data is key. If you want to manually show a form, simply call one of the following methods. ### Bug reporting form The bug reporting form is the default form for bug reports and allows users to mark bugs and add a description as well as their email address. ```javascript theme={null} // Starts a classic bug reporting form. Gleap.startClassicForm({ formId: "bugreporting", showBackButton: false, }); ``` The first parameter determines the flow that should be started. The second parameter allows you to pass the `showBackButton` form option. ### Feature request form This form is great if you want to collect feature requests. You can also embed your Gleap roadmap and share it with your users to have them vote on requests. ```javascript theme={null} // Starts a classic feature request form. Gleap.startClassicForm({ formId: "featurerequests", showBackButton: false, }); ``` ### Custom forms Gleap also allows you to configure custom forms. This is especially handy if our default forms don't fully cover your use cases. Visit our dashboard for more information on custom forms. Classic forms ```javascript theme={null} // Starts a classic form with the CUSTOM_FORM_KEY as key. Gleap.startClassicForm({ formId: "CUSTOM_FORM_KEY", showBackButton: false, }); ``` # Help center Source: https://docs.gleap.io/documentation/ioniccapacitor/helpcenter Happier customers, fewer support questions. What’s not to like? Make it easy for users to access information with our help center articles. Release notes and news for your app or website **Show help center articles** directly within the **Gleap widget**, to offer customers the help they need at the right place & time. ## Open the help center by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openHelpCenter({ showBackButton: true, }); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a help center article by code If you'd like to open a help center article directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openHelpCenterArticle({ articleId: "articleId", showBackButton: false, }); ``` *The first parameter **articleId** can be found at the bottom of your article editor in the **Share this article** banner.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a help center collection by code If you'd like to open a collection directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openHelpCenterCollection({ collectionId: "collectionId", showBackButton: false, }); ``` *The first parameter **collectionId** can be found at the bottom of collection in the **Share this collection** banner.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Search your help center If you'd like to search for help articles, you can do so by calling the following method: ```javascript theme={null} Gleap.searchHelpCenter({ term: "Search term", showBackButton: false, }); ``` *The first parameter **term** defines the search term, the Gleap SDK will look for to find related articles.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # In-app notifications Source: https://docs.gleap.io/documentation/ioniccapacitor/in-app-push-notifications With Gleap, in-app notifications appear directly within the app when a new message is sent to a customer who has the app open. The same applies to news updates. We also support push notification. Please see the push notifications documentation for more information on it. ## Disable in-app notifications The following method allows you to disable the in app notifications. ```js theme={null} Gleap.setDisableInAppNotifications(true); ``` ## Notification container offset You can adjust the position of the in-app notification container by setting an offset in pixels: ```js theme={null} Gleap.setNotificationContainerOffset({ x: x, y: y }); ``` * **x** – Horizontal offset in pixels (positive values move the container to the right). * **y** – Vertical offset in pixels (positive values move the container down). # Network logs Source: https://docs.gleap.io/documentation/ioniccapacitor/network-logs Gleap allows you to log all network requests, to get a better understanding of what went wrong. This usually works out of the box and can be enabled within our visual widget configurator. !\[Netowork logs within the Visual Widget Configurator]\(./images/Bildschirmfoto 2021-12-14 um 10.47.18.png) ## Filtering network logs Gleap allows you to strip off specific key/value pairs from network logs. This empowers you to easily remove sensitive data like `tokens, passwords` or `usernames`. ### How does it work? Log in to the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now enable the `network log filters` option (within the advanced options tab). Once the option is enabled, you can add multiple keys to the array bellow, which should be excluded. All keys, which you add to the exclusion list, will be loaded together with the widget configuration. Before sending a feedback item to our backend, the client SDK will loop through all network requests and stripe off all matching key/value pairs from the `request headers`, `header-payload` (if it's a JSON) and `response body` (if it's a JSON). This ensures that sensitive information will never even leave the client application. #### Example: If you want to remove the Authorization bearer token from your requests, simply add "Authorization" to the list of keys. Network log filters ### Set filter with code It's also possible to set the network log filters by code. ```javascript theme={null} // Manually set the network logs filters Gleap.setNetworkLogPropsToIgnore(["api-key", "user.password", "..."]); ``` ## Blacklisting URLs It is possible to blacklist URLs or parts of URLs. If a network request matches one of the entries in the blacklist, the network request won't be included in the network logs. To add a new entry to the blacklist, simply navigate to your project in the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now click on `Developer options` and add the desired URLs. ### Set blacklist with code It's also possible to set the network log blacklist by code. ```javascript theme={null} // Manually set the network logs blacklist Gleap.setNetworkLogsBlacklist(["https://api.gleap.io", "..."]); ``` # Prefill the widget form Source: https://docs.gleap.io/documentation/ioniccapacitor/prefill-form-data In some situations you might want to prefill some fields for the user. This can be achieved by the following method. ```javascript theme={null} Gleap.preFillForm({ data: { description: "This text will be prefilled.", errordescription: "This text will be prefilled as well.", someformidentifier: "This text will also be prefilled.", }, }); ``` You need to pass a key value pair to the `preFillMethod`. The key is the form identifier, which can be found under the 'Advanced' section of a question. (see screenshot for an example) Form identifier # Push notifications Source: https://docs.gleap.io/documentation/ioniccapacitor/push-notifications Stay connected with your customers by utilizing push notifications to alert them of new chat messages, release notes, and news articles. This will deepen engagement and foster stronger relationships. Gleap supports Firebase Cloud Messaging to send push notifications to users. ## Setup Firebase Cloud Messaging To make use of Gleap Push Notifications you must add the Firebase Cloud Messaging service to your app or website. Learn how to get started with FCM here. ## Getting your Firebase Cloud Messaging Token Open your project in Firebase and open the project settings. Click on "Cloud Messaging" and, if it is not already enabled, activate the Firebase Cloud Messaging API (V1). Gleap Firebase Setup Proceed to the "Service Accounts" section and generate a new private key, which will automatically create a file named like `serviceAccountKey.json`. Gleap Firebase Setup Next, open the project settings in Gleap, select "Push Notifications", and upload the `serviceAccountKey.json` file. Finally, save your configuration. Gleap Push Notifications Setup ## Subscribe to the Gleap user topic The last step to complete the push notification setup is to subscribe to the user topic, which Gleap will send the push notifications to. In order to do so, you will need to register the register & unregister push message topic callbacks. ```js theme={null} // Find more information here: // https://github.com/capacitor-community/fcm import { FCM } from "@capacitor-community/fcm"; import { PushNotifications } from "@capacitor/push-notifications"; // external required step // register for push await PushNotifications.requestPermissions(); await PushNotifications.register(); // Subscribe & unsubscribe to the Gleap topics Gleap.registerListener("registerPushMessageGroup", (topic) => {}); Gleap.setEventCallback((message, err) => { const { name, data } = message; if (name === "register-pushmessage-group") { FCM.subscribeTo({ topic: data }) .then((r) => alert(`subscribed to topic`)) .catch((err) => console.log(err)); } if (name === "unregister-pushmessage-group") { FCM.unsubscribeFrom({ topic: data }) .then((r) => alert(`unsubscribed to topic`)) .catch((err) => console.log(err)); } }); ``` That's it - build and run your app 🚀 ## Notification images When a changelog or news article with a featured image is sent as a push notification, Gleap includes the image in the FCM payload. * **Android** displays the image automatically when the notification arrives while your app is in the background — no setup required. * **iOS** requires a Notification Service Extension in your app to display the image. Follow the native setup in the [iOS push notification guide](/documentation/ios/push-notifications#notification-images) — the extension is added to the iOS project in Xcode and works unchanged in a Capacitor app. # Release notes & news Source: https://docs.gleap.io/documentation/ioniccapacitor/release-notes-and-news Gleap allows you to share release notes & news articles with your customers. Release notes and news for your app or website You can send release notes & news directly within the Gleap Dashboard. Once sent, the user gets notified when he starts his next session. ## Open the news section by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openNews({ showBackButton: true, }); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a news article by code If you'd like to manually a news article directly within the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openNewsArticle({ articleId: "articleId", showBackButton: true, }); ``` *The first parameter **articleId** defines the article to show.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # Surveys Source: https://docs.gleap.io/documentation/ioniccapacitor/surveys Gleap allows you to create micro surveys to be run directly in your Gleap widget. We offer templates for some of the most common survey types, such as NPS scores, product market fit or product satisfaction. ## Sending surveys with triggers Usually customers use triggers to send surveys. Example use cases for that include: * Sending surveys after a certain amount of time * Sending a survey on a certain page * Sending a survey after a specific event happened * ... In order to get started with survey triggers, you need to start tracking events. Once an event has been tracked, you can use it as trigger in the survey options. You can find more information about tracking events [here](./track-events). Gleap survey triggers ## Manually sending surveys You can also manually send surveys to your users. For this you only need to call the following method: ```js theme={null} Gleap.showSurvey({ surveyId: "survey_id", format: "survey", }); ``` The first parameter is the survey id, the second parameter is the format of the survey. The format can be either `survey` (default: card style survey) or `survey_full` (full screen survey). Please note that the Gleap SDK needs to be fully initialized to be able to show a survey. ## Send surveys with URL parameters (Web SDK only) You can also send surveys with URL parameters. This is useful if you want to send surveys to specific users. For example, you can send a survey to a specific user by sending them a link like this: ``` https://yourapp.com/?gleap_survey=\{your-survey-id\}&gleap_survey_format=\{survey\} ``` Please replace \{your-survey-id} with your survey id and \{survey} with the survey format. The survey format can be either "survey" (default: card style survey) or "survey\_full" (full screen survey). The application that you use for sending surveys with URL parameters needs to have the Gleap SDK installed. # Tags Source: https://docs.gleap.io/documentation/ioniccapacitor/tags Gleap allows you to set tags with every feedback item sent from the SDK. To set tags, simply pass an array of Strings to the `setTags` method of the SDK. ## Set tags Set tags to be sent with every feedback item. ```javascript theme={null} Gleap.setTags(["iOS", "Subscribed"]); ``` If you want to update or remove the tags, simply call the method with the updated string array. # Track events Source: https://docs.gleap.io/documentation/ioniccapacitor/track-events Gleap custom events allow you to log events at certain key positions within your application. This is super useful to get an even better understanding of what's happening within an application. Custom events do have a name and can contain event specific data as well. ## Track an event The following sample logs an event with the name "User signed in". ```javascript theme={null} Gleap.trackEvent({ name: "User signed in", }); ``` ## Track an event with attached data It's possible to attach data to custom events. The data can be viewed later in the respective bug report. ```javascript theme={null} Gleap.trackEvent({ name: "User signed in", data: { userId: 1242, name: "Isabella", skillLevel: "🤩", }, }); ``` Your events will appear in the activity log of the bug report. # Track pages Source: https://docs.gleap.io/documentation/ioniccapacitor/track-pages Automatic page tracking is not available for ReactNative due to platform limitations. We highly encourage you to still track pages with the following helper method. ## Track a page ```javascript theme={null} Gleap.trackPage("HomePage"); ``` You will be able to use the tracked pages as triggers in outbound messages as well as breadcrumbs for debugging. # Translations Source: https://docs.gleap.io/documentation/ioniccapacitor/translations Gleap was built for people around the world and offers translations for many languages by default. If we are missing a language or translation, you can simply add an additional language yourself in our visual widget configurator. Gleap automatically picks the device language as default language. If the device language is not available it will switch to English as a fallback. In some situations you might want to overwrite the device language with a custom language. This can be achieved with the following method. ### Overwrite the default language ```javascript theme={null} // 2 digit ISO code Gleap.setLanguage({ languageCode: "es", }); // 5 digit ISO code with lang - country Gleap.setLanguage({ languageCode: "en-US", }); ``` Please use the `setLanguage` method only before the initialization of the Gleap SDK (before calling `Gleap.initialize()`) # User identity Source: https://docs.gleap.io/documentation/ioniccapacitor/user-identity The Gleap Identify call lets you tie a user to their feedback items. It includes a unique User ID and optional meta information such as their email and name. ### Identify your users To effectively manage your contacts, we advise using `Gleap.identify()` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `Gleap.updateContact()`. This method allows for seamless real-time updates to contact details. Identify your user by calling the following method. ```javascript theme={null} Gleap.identify({ userId: "19283", name: "Franz", email: "franz@gleap.io", phone: "+1 (902) 123123", value: 199.95, avatar: "https://.../avatar.png", customData: { plan: "Pro plan", company: "ACME inc.", }, }); ``` When transmitting custom data, only primitive numeric and string values are supported for later use in segment filters. Please note that you can send only 35 custom data keys with an identify call. We currently only allow JSON strings, numbers and boolean values as custom data. Gleap defaults to guest sessions when feedback items get reported without calling the identify method first. All feedback items of an existing guest session will be merged with the user session once you've identified it. ### Enforce identity verification Enforce identity verification to prevent third parties from impersonating logged-in users. [Learn how to generate the user hash](../guides/enforce-identity-verification) ```js theme={null} Gleap.identify({ userId: "19283", name: "Franz", email: "franz@gleap.io", userHash: "GENERATED_USER_HASH", phone: "+1 (902) 123123", value: 199.95, avatar: "https://.../avatar.png", customData: { plan: "Pro plan", company: "ACME inc.", }, }); ``` [Click here](../guides/enforce-identity-verification.mdx) to learn how to generate the user hash. ### Update contact properties To effectively manage your contacts, we advise using `Gleap.identify()` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `Gleap.updateContact()`. This method allows for seamless real-time updates to contact details. ```javascript theme={null} Gleap.updateContact({ value: 199.95, plan: "Pro plan", }); ``` The updateContact method takes in the same contact parameters as the identify method. Partial updates are possible. ```javascript theme={null} Gleap.updateContact({ name: "Franz", email: "franz@gleap.io", phone: "+1 (902) 123123", value: 199.95, plan: "Pro plan", avatar: "https://.../avatar.png", companyId: "12398958484", companyName: "ACME inc.", customData: { key1: "awesome", key2: true, }, }); ``` ### Clear the identity on logout We recommend to clear the identity once the user logs out. Clearing the identity will automatically detach the current session and create a new guest session. ```js theme={null} Gleap.clearIdentity(); ``` ### Get the identification status of a user With the following method, you can get the status of the current user identity. ```js theme={null} Gleap.isUserIdentified(); ``` ### Get the current user identity With the following method, you can get the current user identity. ```js theme={null} Gleap.getIdentity(); ``` # Widget control Source: https://docs.gleap.io/documentation/ioniccapacitor/widget-control In some situations you might want to take full control over showing or hiding the Gleap widget. This can be achieved with the following methods. ### Open the Gleap widget ```javascript theme={null} Gleap.open(); ``` ### Close the Gleap widget ```javascript theme={null} Gleap.close(); ``` If you want to get notified of certain events, check out the [events](events.md) documentation page. ### Widget open status It's possible to request the widget open status with the following method. ```javascript theme={null} const isOpened = Gleap.isOpened(); ``` # Introducing Source: https://docs.gleap.io/documentation/ios/README The Gleap SDK for iOS is the easiest way to integrate Gleap into your apps. Communicate with your users directly and build better software by discovering their everyday pain points. Gleap is your all-in-one customer feedback tool for apps and websites. For the SDK to work, you need an API key, which you can get for free at [app.gleap.io](https://app.gleap.io). ## 🏗 Installation The Gleap SDK uses CocoaPods to install and manage dependencies. Open a terminal window and navigate to the root folder of your iOS project. ### Install the Gleap SDK The Gleap SDK supports the **Swift Package Manager** and **CocoaPods**. To get started, open your Xcode project and select **File** > **Add packages...** Now you need to paste the following package URL to the search bar in the top right corner. Hit enter to confirm the search. **Package URL:** ```js theme={null} https://github.com/GleapSDK/Gleap-iOS-SDK ``` Now select the Gleap package and hit **Add package** to add the Gleap SDK to your project. Gleap package for Swift Package Manager #### Create a [Podfile](https://guides.cocoapods.org/using/the-podfile.html), and add your dependencies: ``` pod 'Gleap', '>= 17.0.0' ``` #### #### Save the file and run the following command. ``` pod install ``` These steps create a .xcworkspace file for your app. Make sure to open this file for further developments on your application. ### Initialize the SDK Open your project in XCode and navigate to your **app delegate** or main **App class** when using SwiftUI. #### Import the Gleap SDK Add the following import under your other imports. ```swift theme={null} import Gleap ``` ```objectivec theme={null} // When using Swift Package Manager @import Gleap // When using CocoaPods #import ``` ### Initialize the SDK The last step is to initialize & configure the Gleap SDK by adding the following code to the end of your *applicationDidFinishLaunchingWithOptions* delegate or *init()* method of your main app (SwiftUI). ```swift theme={null} Gleap.initialize(withToken: "API-TOKEN") ``` ```objectivec theme={null} [Gleap initializeWithToken: @"API-TOKEN"]; ``` Congratulations 🎉 You are now all set 👋 ## Required permissions In order to use the image picker for attachments, add the following permissions to your `Info.plist`. ``` NSPhotoLibraryUsageDescription We need access to your photo library to allow you to select an image. NSCameraUsageDescription We need access to your camera to take photos. ``` The following permissions are needed to enable audio recordings. ``` NSMicrophoneUsageDescription We need access to your microphone to record audio with videos. ``` ## 🤝 Need help? We are here to help! [hello@gleap.io](mailto:hello@gleap.io) # Frontend tools Source: https://docs.gleap.io/documentation/ios/aitools Frontend tools let your AI agent execute actions directly inside your app — initiating a transfer, resetting a password, cancelling an order, etc. Tools are defined on your AI agent in the Gleap dashboard (**AI agent > Tools > Frontend tool**) — name, description, parameters and execution mode all live there. Your app only registers a handler that executes the tool. Learn how to set up Frontend tools in our [help center article](https://help.gleap.io/en/articles/221-frontend-tools-let-the-ai-run-actions-in-your-app). ## Register a tool handler Register the handler for a dashboard-defined Frontend tool. Use the tool's runtime name shown in the tool editor. ```swift theme={null} Gleap.registerAgentTool("send-money") { params, completion in let amount = params["amount"] let contact = params["contact"] // Run your own logic here. // Return a string or JSON — the AI waits for this response. completion("The transfer was initiated. The user must confirm it in the banking app.") } ``` **Handler contract** * The handler is invoked on the main queue with the parameters configured in the dashboard, filled with the values the AI collected. * Call the completion block exactly once with the result — a string or a JSON object (dictionaries and arrays are stringified). The result is sent back to the AI, which uses it to reply. * The completion block can be called asynchronously — the AI waits for it. * Exceptions thrown by the handler are caught and reported to the AI automatically. * If no handler is registered for a tool, the AI is informed so it can respond accordingly. ## Execution modes Set per tool in the dashboard: * `Auto` — the handler runs immediately when the AI calls the tool. * `Ask before final execution` — the AI adds a confirmation button to its reply; the handler only runs after the user confirms. ## Migrating from `setAiTools` `Gleap.setAiTools(...)` and the `GleapAiTool` / `GleapAiToolParameter` classes have been removed. Tools defined via `setAiTools` could only return a static response to the AI — Frontend tools execute real code and return live results. Define your tools on the AI agent in the dashboard and register their handlers via `Gleap.registerAgentTool(_:handler:)` instead. The `onToolExecution` delegate method remains available. # Audio recording Source: https://docs.gleap.io/documentation/ios/audio-recording Available starting from version 14.2.0. Gleap allows users to record audio messages when chatting with support. This is a great way to collect feedback from users. ## Additional setup In order for audio recording to work for iOS, you need to add the following key to your `Info.plist` file: ```xml theme={null} NSMicrophoneUsageDescription We need access to the microphone to record audio messages. ``` This key is required by iOS to allow the app to use the microphone. ## Enable the audio recording feature To enable the audio recording feature, navigate to `AI chatbot` -> `Settings` and toggle the `Allow audio messages` switch. # Checklists Source: https://docs.gleap.io/documentation/ios/checklists Dive into a completely refreshed onboarding experience that will guide your users with gusto. The new checklist feature not only ensures your users are thoroughly onboarded but also keeps them deeply engaged. All of this is neatly packed inside our Gleap widget! ## Open the checklists overview Open the checklists overview with the method below. ```objective-c theme={null} [Gleap openChecklists]; ``` ## Manually start a checklist Checklists can be sent either through trigger rules or manually with the method below. ```objective-c theme={null} [Gleap startChecklist: @"outboundId" andShowBackButton: YES]; ``` You can find the outboundId within the checklist editor. Please note that SDK version 12.1.0 or higher is required to send checklists. # Console logs Source: https://docs.gleap.io/documentation/ios/console-logs The Gleap iOS SDK collects console logs for the `Release` profile by default. Further more you can make use of our custom logs, which offer more control over the logs. ## Default console logs Console logs are enabled by default on `Release` profile builds. In debug mode, console logs are disabled by default. ### Enable console logs in debug mode You can enable console logs in debug mode by calling the following method. Make sure to call this method `BEFORE` initializing the Gleap SDK. ``` [Gleap enableDebugConsoleLog]; ``` Please note that this can lead to freezing or crashing applications, depending on what 3rd party libraries you have installed. If you encounter an app freeze with this option enabled, please disable it again or remove 3rd parties, that also rewire the console logs (like Firebase Crashlytics or Sentry). ### Disable default console logs It is possible to disable the default collection of console logs by calling the following method prior to the initialization of Gleap. ``` [Gleap disableConsoleLog]; ``` ## Custom logs Custom logs allow you to create logs in the Gleap activity log. There are three severnity types available for logs: `ERROR`, `WARNING` and `INFO`. ``` [Gleap log: @"This is a test log."]; ``` By default logs will be created with the severnity `INFO`. Use the following method to explicitly set the severnity. ``` [Gleap log: @"This is a test error." withLogLevel: ERROR]; ``` # Conversations Source: https://docs.gleap.io/documentation/ios/conversations Conversations ## Start a new conversation You can manually start a new conversation with the following method: ```javascript theme={null} Gleap.startConversation(true); ``` Open the conversation history If you'd like to manually show the conversation history of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openConversations(); ``` # Custom actions Source: https://docs.gleap.io/documentation/ios/custom-actions We know that the built in actions (Bug Reporting, Feature Requests, Ratings & Contact Us) might not be enough for certain use cases. For these situations we offer custom actions, which allow you to start any custom action by code. ## Configure a custom action The first step with custom actions is to open the visual widget configurator and select **"Custom action"** as action type. Now you need to **set a name for your custom action**. Choose any name you like (it's however important that this name matches the name you check in the next step). Setup custom actions in the Gleap dashboard. ## Custom action callback Once you've set a custom action in the Gleap dashboard, it will be called automatically on selection through the user. In order to perform custom code, simply implement our `GleapDelegate` to receive the custom action events. ### Add & implement the Gleap delegate The following code sample shows how to implement the `GleapDelegate` protocol. ```swift theme={null} import Foundation import UIKit import Gleap // Add the GleapDelegate protocol to your view controller class DemoViewController: UIViewController, GleapDelegate { override func viewDidLoad() { // Assign self to the delegate Gleap.sharedInstance().delegate = self; } // Add the custom action called implementation func customActionCalled(_ customAction: String) { if (customAction == "MAGIC_ACTION") { print("Magic action got called.") } } } ``` The **custom action name** is defined by you in the visual widget configurator on the Gleap dashboard. You can also retrieve the ticket shareToken in the custom action callback like below. ```swift theme={null} import Foundation import UIKit import Gleap // Add the GleapDelegate protocol to your view controller class DemoViewController: UIViewController, GleapDelegate { override func viewDidLoad() { // Assign self to the delegate Gleap.sharedInstance().delegate = self; } // Add the custom action called implementation func customActionCalled(_ customAction: String, withShareToken shareToken: String?) { // For custom actions triggered within tickets, shareToken will be set to identify the ticket. if (customAction == "MAGIC_ACTION") { print("Magic action got called.") } } } ``` # Custom data Source: https://docs.gleap.io/documentation/ios/custom-data ## Add custom data In many situations you may want to attach custom data to feedback items in order to better understand the context. You can add custom data incrementally or all at once. Any simple JSON object can be attached. ```swift theme={null} Gleap.attachCustomData(["value": "Magic", "type": "Unicorn"]) ``` ## Append custom data If you want to attach custom data incrementally, you can do so with the `setCustomData` method. ```swift theme={null} Gleap.setCustomData("Magic & awesome", forKey: "value") ``` ## Remove custom data Remove custom data key value pairs by calling the following method. ```swift theme={null} Gleap.removeCustomData(forKey: "value") ``` ## Clear all custom data It's possible to clear all attached custom data by calling the following method. ```swift theme={null} Gleap.clearCustomData(); ``` # Custom URL handler Source: https://docs.gleap.io/documentation/ios/custom-url-handler In certain applications, having granular control over how hyperlinks are managed is crucial. This document outlines how to override the default URL handling behavior in your iOS app using the Gleap framework. By configuring a custom URL handler, you delegate the responsibility of opening URLs from the Gleap framework to a handler of your choosing. This allows for tailored handling of URL interactions based on the specific needs of your application. ## Configure the URL handler Use our `GleapDelegate` protocol. This protocol includes the method that handles URL loading: ```swift theme={null} import Foundation import UIKit import Gleap // Add the GleapDelegate protocol to your view controller class DemoViewController: UIViewController, GleapDelegate { override func viewDidLoad() { // Assign self to the delegate Gleap.sharedInstance().delegate = self; } func openExternalLink(_ url: URL) { // Handle url } } ``` # Callbacks Source: https://docs.gleap.io/documentation/ios/events Use our GleapDelegate to get notified on certain state changes of the Gleap widget. This enables you to create an even deeper integration with Gleap. ```swift theme={null} import Foundation import UIKit import Gleap // Add the GleapDelegate protocol to your view controller class DemoViewController: UIViewController, GleapDelegate { override func viewDidLoad() { // Assign self to the delegate Gleap.sharedInstance().delegate = self; } func notificationCountUpdated(_ count: Int32) { NSLog("Notification count updated. %i", count); } func widgetClosed() { NSLog("Closed widget.") } func initialized() { NSLog("Gleap got initialized and is ready.") } func widgetOpened() { NSLog("Opened widget.") } func feedbackFlowStarted(_ feedbackAction: [AnyHashable : Any]) { NSLog("Form shown", feedbackAction) } func feedbackSendingFailed() { NSLog("Sending form failed") } func feedbackSent(_ data: [AnyHashable : Any]) { NSLog("Form sent", data) } func customActionCalled(_ customAction: String) { NSLog(customAction) } } ``` ## # Feature requests Source: https://docs.gleap.io/documentation/ios/feature-requests The new Gleap widget offers a feature request view allowing users to view, upvote & comment more easily on feature requests. Release notes and news for your app or website You can enable the feature requests view directly within the Gleap Dashboard or show it by code. ## Open the feature requests app by code If you'd like to manually show the feature requests app of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openFeatureRequests(NO); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # Feedback button Source: https://docs.gleap.io/documentation/ios/feedback-button In some situations you might want to take full control over the feedback button. In order to show or hide the feedback button, you can simply use the following methods. ### Show the feedback button ```javascript theme={null} Gleap.showFeedbackButton(true); ``` ### Hide the feedback button ```javascript theme={null} Gleap.showFeedbackButton(false); ``` Gleap feedback button with live chat bubble # Forms Source: https://docs.gleap.io/documentation/ios/feedback-flows Gleap forms are a traditional, straightforward approach for user data input. They offer a simple, efficient method for users to provide specific information or feedback. Forms are particularly useful when detailed user input is essential, allowing for a clear, direct way of data collection without the dynamic steps involved in workflows. This makes forms a reliable option for scenarios where straightforward, user-provided data is key. If you want to manually show a form, simply call one of the following methods. ### Bug reporting form The bug reporting form is the default form for bug reports and allows users to mark bugs and add a description as well as their email address. ```javascript theme={null} // Starts a classic bug reporting form. Gleap.startClassicForm("bugreporting", showBackButton: true); ``` The first parameter determines the flow that should be started. The second parameter allows you to pass the `showBackButton` form option. ### Feature request form This form is great if you want to collect feature requests. You can also embed your Gleap roadmap and share it with your users to have them vote on requests. ```javascript theme={null} // Starts a classic feature request form. Gleap.startClassicForm("featurerequests", showBackButton: true); ``` ### Custom forms Gleap also allows you to configure custom forms. This is especially handy if our default forms don't fully cover your use cases. Visit our dashboard for more information on custom forms. Classic forms ```javascript theme={null} // Starts a classic form with the CUSTOM_FORM_KEY as key. Gleap.startClassicForm("CUSTOM_FORM_KEY", showBackButton: true); ``` # Help center Source: https://docs.gleap.io/documentation/ios/helpcenter Happier customers, fewer support questions. What’s not to like? Make it easy for users to access information with our help center articles. Release notes and news for your app or website **Show help center articles** directly within the **Gleap widget**, to offer customers the help they need at the right place & time. ## Open the help center by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openHelpCenter(false); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a help center article by code If you'd like to open a help center article directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openHelpCenterArticle("articleId", andShowBackButton: false) ``` *The first parameter **articleId** can be found at the bottom of your article editor in the **Share this article** banner.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a help center collection by code If you'd like to open a collection directly withing the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openHelpCenterCollection("collectionId", andShowBackButton: false) ``` *The first parameter **collectionId** can be found at the bottom of collection in the **Share this collection** banner.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Search your help center If you'd like to search for help articles, you can do so by calling the following method: ```javascript theme={null} Gleap.searchHelpCenter("Search term", andShowBackButton: false) ``` *The first parameter **term** defines the search term, the Gleap SDK will look for to find related articles.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # In-app notifications Source: https://docs.gleap.io/documentation/ios/in-app-push-notifications With Gleap, in-app notifications appear directly within the app when a new message is sent to a customer who has the app open. The same applies to news updates. We also support push notification. Please see the push notifications documentation for more information on it. ## Disable in-app notifications The following method allows you to disable the in app notifications. ```js theme={null} Gleap.setDisableInAppNotifications(true); ``` ## Notification container offset You can adjust the position of the in-app notification container by setting an offset in pixels: ```objectivec theme={null} [Gleap setNotificationContainerOffsetX: x y: y]; ``` * **x** – Horizontal offset in pixels (positive values move the container to the right). * **y** – Vertical offset in pixels (positive values move the container down). # Network logs Source: https://docs.gleap.io/documentation/ios/network-logs Gleap allows you to log all network requests, to get a better understanding of what went wrong. This usually works out of the box, but needs additional configuration, depending on the 3rd party libraries you are using within your applications. ## Setting up network logs ``` Gleap.startNetworkRecording(); ``` ```objectivec theme={null} [Gleap startNetworkRecording]; ``` ### AFNetworking To enable network logging for AFNetworking, create and use the following class. ```objectivec theme={null} // GleapAFURLSessionManager.h #import @interface GleapAFURLSessionManager : AFHTTPSessionManager @end // GleapAFURLSessionManager.m #import "GleapAFURLSessionManager.h" #import @implementation GleapAFURLSessionManager - (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration { [Gleap startNetworkRecordingForSessionConfiguration: configuration]; return [super initWithSessionConfiguration:configuration]; } @end ``` Example usage for the `GleapAFURLSessionManager`. ```objectivec theme={null} // Use the GleapAFURLSessionManager for all further requests NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; GleapAFURLSessionManager *manager = [[GleapAFURLSessionManager alloc] initWithSessionConfiguration: configuration]; [manager GET: @"https://www.example.org/get" parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"JSON: %@", responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"Error: %@", error); }]; ``` ### Alamofire To enable network logging for Alamofire, create and use the following class. ```objectivec theme={null} import Alamofire import Gleap class GleapSessionManager: Alamofire.Session { static let sharedManager: GleapSessionManager = { let configuration = URLSessionConfiguration.default Gleap.startNetworkRecording(for: configuration) let manager = GleapSessionManager(configuration: configuration) return manager }() } ``` Example usage for the Gleap`SessionManager`. ```objectivec theme={null} GleapSessionManager.sharedManager.request("https://www.sample.org/get").response { response in debugPrint(response) } ``` ### Moya The Gleap Moya plugin intercepts all requests and forwards them to the Gleap SDK. #### Installation ##### Swift Package Manager To get started, open your Xcode project and select *File* > *Add packages...* Now you need to paste the following package URL to the search bar in the top right corner. Hit enter to confirm the search. Package URL: ``` https://github.com/GleapSDK/Gleap-iOS-Moya-Plugin ``` Now select the Gleap package and hit *Add package* to add the Gleap SDK to your project. ##### Manual installation Simply copy the GleapMoyaPlugin.swift (Sources/GleapMoyaPlugin) from this repository into your project. In addition to that make sure to install Gleap & Moya. #### Using the plugin After installing the plugin, you can use it by simply declaring it during the initialization of your Moya provider: ``` let provider = MoyaProvider(plugins: [GleapMoyaPlugin()]) ``` #### Using an older Moya version? If you are using an older Moya version, simply use the GleapMoyaPlugin from [here](https://gist.github.com/boehlerlukas/0e54a1a0c8377ba5cd519faa6f3b7bb1). ## Filtering network logs Gleap allows you to strip off specific key/value pairs from network logs. This empowers you to easily remove sensitive data like `tokens, passwords` or `usernames`. ### How does it work? Log in to the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now enable the `network log filters` option (within the advanced options tab). Once the option is enabled, you can add multiple keys to the array bellow, which should be excluded. All keys, which you add to the exclusion list, will be loaded together with the widget configuration. Before sending a feedback item to our backend, the client SDK will loop through all network requests and stripe off all matching key/value pairs from the `request headers`, `header-payload` (if it's a JSON) and `response body` (if it's a JSON). This ensures that sensitive information will never even leave the client application. #### Example: If you want to remove the Authorization bearer token from your requests, simply add "Authorization" to the list of keys. !\[Network log filter]\(./images/Bildschirmfoto 2021-12-14 um 11.16.06.png) ### Set filter with code It's also possible to set the network log filters by code. ```javascript theme={null} // Manually set the network logs filters Gleap.setNetworkLogPropsToIgnore(["api-key", "user.password", "..."]); ``` ## Blacklisting URLs It is possible to blacklist URLs or parts of URLs. If a network request matches one of the entries in the blacklist, the network request won't be included in the network logs. To add a new entry to the blacklist, simply navigate to your project in the [Gleap dashboard](https://app.gleap.io) and open the visual widget configurator. Now click on `Developer options` and add the desired URLs. ### Set blacklist with code It's also possible to set the network log blacklist by code. ```javascript theme={null} // Manually set the network logs blacklist Gleap.setNetworkLogsBlacklist(["https://api.gleap.io", "..."]); ``` # Prefill the widget form Source: https://docs.gleap.io/documentation/ios/prefill-form-data In some situations you might want to prefill some fields for the user. This can be achieved by the following method. ```javascript theme={null} [Gleap preFillForm: @{ @"description": @"This text will be prefilled.", @"errordescription": @"This text will be prefilled as well.", @"someformidentifier": @"This text will also be prefilled." }]; ``` You need to pass a key value pair to the `preFillMethod`. The key is the form identifier, which can be found under the 'Advanced' section of a question. (see screenshot for an example) Form identifier # Push notifications Source: https://docs.gleap.io/documentation/ios/push-notifications Stay connected with your customers by utilizing push notifications to alert them of new chat messages, release notes, and news articles. This will deepen engagement and foster stronger relationships. Gleap supports Firebase Cloud Messaging to send push notifications to users. ## Setup Firebase Cloud Messaging To make use of Gleap Push Notifications you must add the Firebase Cloud Messaging service to your app or website. Learn how to get started with FCM here. ## Getting your Firebase Cloud Messaging Token Open your project in Firebase and open the project settings. Click on "Cloud Messaging" and, if it is not already enabled, activate the Firebase Cloud Messaging API (V1). Gleap Firebase Setup Proceed to the "Service Accounts" section and generate a new private key, which will automatically create a file named like `serviceAccountKey.json`. Gleap Firebase Setup Next, open the project settings in Gleap, select "Push Notifications", and upload the `serviceAccountKey.json` file. Finally, save your configuration. Gleap Push Notifications Setup ## Subscribe to the Gleap user topic The last step to complete the push notification setup is to subscribe to the user topic, which Gleap will send the push notifications to. In order to do so, you will need to register the register & unregister push message topic callbacks. ``` import Foundation import UIKit // Don't forget the imports import Gleap import Firebase import FirebaseMessaging // Add the GleapDelegate protocol to your view controller class DemoViewController: UIViewController, GleapDelegate { override func viewDidLoad() { // Assign self to the delegate Gleap.sharedInstance().delegate = self; } func registerPushMessageGroup(_ pushMessageGroup: String) { // Register topic Messaging.messaging().subscribe(toTopic: pushMessageGroup) { error in } } func unregisterPushMessageGroup(_ pushMessageGroup: String) { // Unregister topic Messaging.messaging().unsubscribe(fromTopic: pushMessageGroup) { error in } } } ``` That's it - build and run your app 🚀 ## Handle push-notifications click In order to open the message, the user clicked on, you will need to add some extra code to your app. The idea is to get the data from the push notification and then pass it to the SDK by utilizing handlePushNotification(). Please note depending on your specific code, the callbacks might be different. The important part is to forward the notification data to `Gleap.handlePushNotification()`. ```js theme={null} import UIKit import Foundation import Gleap @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo print("Handle push from background or closed \(userInfo)") // Check for specific notification indicating it's from "GLEAP" if let sender = userInfo["sender"] as? String, sender == "GLEAP" { Gleap.handlePushNotification(userInfo) } completionHandler() } // Add other necessary AppDelegate methods... } ``` ## Notification images When a changelog or news article with a featured image is sent as a push notification, Gleap includes the image in the push payload (`mutable-content` is set and the image URL is delivered via `fcm_options.image`). On iOS, displaying an image in a notification requires a **Notification Service Extension** in your app — without it, the notification is still delivered, just without the image. 1. In Xcode, select **File → New → Target…** and choose **Notification Service Extension**. 2. Add the `FirebaseMessaging` dependency to the new extension target (via Swift Package Manager or CocoaPods). 3. Replace the generated `NotificationService.swift` with: ```js theme={null} import UserNotifications import FirebaseMessaging class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) guard let bestAttemptContent = bestAttemptContent else { return } // Downloads the image from fcm_options.image and attaches it to the notification. Messaging.serviceExtension().populateNotificationContent(bestAttemptContent, withContentHandler: contentHandler) } override func serviceExtensionTimeWillExpire() { if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } } ``` # Release notes & news Source: https://docs.gleap.io/documentation/ios/release-notes-and-news Gleap allows you to share release notes & news articles with your customers. Release notes and news for your app or website You can send release notes & news directly within the Gleap Dashboard. Once sent, the user gets notified when he starts his next session. ## Open the news section by code If you'd like to manually show the news section of the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openNews(false); ``` *The first parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* ## Open a news article by code If you'd like to manually a news article directly within the Gleap widget, you can do so by calling the following method: ```javascript theme={null} Gleap.openNewsArticle("articleId", andShowBackButton: false) ``` *The first parameter **articleId** defines the article to show.* *The second parameter **showBackButton** sets whether or not the main tabbar and back buttons will be shown.* # Surveys Source: https://docs.gleap.io/documentation/ios/surveys Gleap allows you to create micro surveys to be run directly in your Gleap widget. We offer templates for some of the most common survey types, such as NPS scores, product market fit or product satisfaction. ## Sending surveys with triggers Usually customers use triggers to send surveys. Example use cases for that include: * Sending surveys after a certain amount of time * Sending a survey on a certain page * Sending a survey after a specific event happened * ... In order to get started with survey triggers, you need to start tracking events. Once an event has been tracked, you can use it as trigger in the survey options. You can find more information about tracking events [here](./track-events). Gleap survey triggers ## Manually sending surveys You can also manually send surveys to your users. For this you only need to call the following method: ```objective-c theme={null} [Gleap showSurvey: @"surveyId" andFormat: SURVEY]; ``` The first parameter is the survey id, the second parameter is the format of the survey. The format can be either `SURVEY` (default: card style survey) or `SURVEY_FULL` (full screen survey). Please note that the Gleap SDK needs to be fully initialized to be able to show a survey. # Tags Source: https://docs.gleap.io/documentation/ios/tags Gleap allows you to set tags with every feedback item sent from the SDK. To set tags, simply pass an array of Strings to the `setTags` method of the SDK. ## Set tags Set tags to be sent with every feedback item. ```javascript theme={null} Gleap.setTags(["iOS", "Subscribed"]); ``` If you want to update or remove the tags, simply call the method with the updated string array. # Ticket attributes Source: https://docs.gleap.io/documentation/ios/ticket-attributes Ticket custom data ## Set ticket attributes Ticket attributes can be set with the method below. If the user also provides data for an attribute (for example `description`), the user input will be prioritized. ```javascript theme={null} Gleap.setTicketAttributeWithKey("notes", value: "This is a test value.") ``` **First param**: attribute key
**Second param**: value (string, boolean, string array or number are supported) Ticket attribute data will not be [pre-filled](ios/prefill-form-data.md) in forms. ## Finding the ticket attribute keys You can find or create all available ticket attributes for each ticket type in **Settings** > **Data attributes**. Ticket attribute ## Unset ticket attributes Ticket attributes can be unset with the method below. ```javascript theme={null} Gleap.unsetTicketAttribute(withKey: "notes") ``` ## Clear all ticket attributes All ticket attributes can be cleared with the method below. ```javascript theme={null} Gleap.clearTicketAttributes(); ``` # Track pages Source: https://docs.gleap.io/documentation/ios/track-pages The iOS SDK tracks pages based on the activity name by default. If you want to customize the tracked pages you can do so by using the trackEvent() method below to track custom pages. ## Track a page ```javascript theme={null} Gleap.trackEvent("trackPage", withData: ["page": "Example page"]) ``` You will be able to use the tracked pages as triggers in outbound messages as well as breadcrumbs for debugging. # Translations Source: https://docs.gleap.io/documentation/ios/translations Gleap was built for people around the world and offers translations for many languages by default. If we are missing a language or translation, you can simply add an additional language yourself in our visual widget configurator. Gleap automatically picks the device language as default language. If the device language is not available it will switch to English as a fallback. In some situations you might want to overwrite the device language with a custom language. This can be achieved with the following method. ### Overwrite the default language ```javascript theme={null} // 2 digit ISO code Gleap.setLanguage("es"); // 5 digit ISO code with lang - country Gleap.setLanguage("en-US"); ``` Please use the `setLanguage` method only before the initialization of the Gleap SDK (before calling `Gleap.initialize()`) # User identity Source: https://docs.gleap.io/documentation/ios/user-identity The Gleap identify call lets you tie a user to their feedback items. It includes a unique User ID and optional meta information such as email & name. ### Identify your users To effectively manage your contacts, we advise using `identifyContact` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `updateContact`. This method allows for seamless real-time updates to contact details. Identify your user by calling the following method. ```swift theme={null} let userProperty = GleapUserProperty() userProperty.name = "Franz" userProperty.email = "franz@gleap.io" userProperty.phone = "+1 (902) 123123" userProperty.value = 199.95 userProperty.plan = "Pro plan"; userProperty.companyId = "29883"; userProperty.companyName = "ACME inc."; userProperty.customData = ["key1": "Custom data"]; Gleap.identifyContact("user_1234", andData: userProperty) ``` ```objectivec theme={null} GleapUserProperty *userProperty = [[GleapUserProperty alloc] init]; userProperty.name = @"Franz"; userProperty.email = @"franz@gleap.io"; userProperty.phone = @"+1 (902) 123123"; userProperty.value = @(199.95); userProperty.plan = @"Pro plan"; userProperty.companyId = @"29883"; userProperty.companyName = @"ACME inc."; userProperty.customData = @{ @"key1": @"Custom data", }; [Gleap identifyContact: @"user_1234" andData: userProperty]; ``` When transmitting custom data, only primitive numeric and string values are supported for later use in segment filters. Please note that you can send only 35 custom data keys with an identify call. We currently only allow JSON strings, numbers and boolean values as custom data. Gleap defaults to guest sessions when feedback items get reported without calling the identify method first. All feedback items of an existing guest session are merged with the user session once you've identified it. ### Enforce identity verification Enforce identity verification to prevent third parties from impersonating logged-in users. [Learn how to generate the user hash](../guides/enforce-identity-verification) ```swift theme={null} let userProperty = GleapUserProperty() userProperty.name = "Franz" userProperty.email = "franz@gleap.io" userProperty.phone = "+1 (902) 123123" userProperty.value = 199.95 userProperty.plan = "Pro plan" userProperty.companyId = "29883" userProperty.companyName = "ACME inc." userProperty.customData = [ "key1": "data", ] Gleap.identifyContact("user_1234", andData: userProperty, andUserHash: "GENERATED_USER_HASH") ``` [Click here](../guides/enforce-identity-verification.mdx) to learn how to generate the user hash. ### Update contact properties To effectively manage your contacts, we advise using `identifyContact` each time a user signs in or registers. This practice ensures accurate identification of your contacts from the outset. Additionally, for scenarios where contact information needs to be updated during active usage – such as when a user subscribes to a new plan or modifies their existing data – we recommend utilizing `updateContact`. This method allows for seamless real-time updates to contact details. ```javascript theme={null} let userProperty = GleapUserProperty(); userProperty.value = 199.95; userProperty.plan = "Pro plan"; Gleap.updateContact(userProperty); ``` The updateContact method takes in the same contact parameters as the identify method. Partial updates are possible. ```javascript theme={null} let userProperty = GleapUserProperty() userProperty.name = "Franz" userProperty.email = "franz@gleap.io" userProperty.phone = "+1 (902) 123123" userProperty.value = 199.95 userProperty.plan = "Pro plan" userProperty.companyId = "29883" userProperty.companyName = "ACME inc." userProperty.customData = [ "key1": "data", ] Gleap.updateContact(userProperty) ``` ### Clear the identity on logout We recommend to clear the identity once the user logs out. Clearing the identity will automatically detach the current session and create a new guest session. ```swift theme={null} Gleap.clearIdentity(); ``` ```objectivec theme={null} [Gleap clearIdentity]; ``` ### Get the identification status of a user With the following method, you can get the status of the current user identity. ```swift theme={null} Gleap.isUserIdentified(); ``` ```objectivec theme={null} [Gleap isUserIdentified]; ``` ### Get the current user identity With the following method, you can get the current user identity. ```swift theme={null} Gleap.getIdentity(); ``` ```objectivec theme={null} [Gleap getIdentity]; ``` # Introduction Source: https://docs.gleap.io/documentation/javascript/README The Gleap SDK for JavaScript is the easiest way to integrate Gleap into your apps. Communicate with your users directly and build better software by discovering their everyday pain points. Gleap is your all-in-one customer feedback tool for apps and websites. For the SDK to work, you need an API key, which you can get for free at [app.gleap.io](https://app.gleap.io). ## 🏗 Installation Installing the Gleap SDK takes only a few seconds. We do offer the following two installation methods. **Code snippet**: This method always loads the latest version of Gleap and is suitable for all use cases. **npm / yarn**: This method allows you to install the Gleap SDK locally and ship it together with your application. This method is usually used with frameworks like **Angular**, **React** or **Vue.js**. Add the following code snippet to the ``-tag of your website or web app. Replace `API-KEY` with your API key. The snippet below will load the Gleap widget asynchronously, to ensure it won't affect your page speed. #### Code snippet ```html theme={null} ``` Install the **Gleap** package via npm or yarn. ``` npm install gleap --save ``` *** **Initialize** the Gleap SDK ```javascript theme={null} import Gleap from "gleap"; // Please make sure to call this method only once! Gleap.initialize("API_KEY"); ``` Congrats! You are now all set 🎉 Report your first bug by using the feedback button ## 😵‍💫 Common pitfalls ### Soft-reloading Some application stacks clear all HTML & CSS while soft reloading (for example with Ruby on Rails). This results in the widget being removed. In order to re-initialize the widget, we recommend doing a soft re-initialization after the soft reload did take place. ```js theme={null} // General Gleap.getInstance().softReInitialize(); // Usage with Turbo (https://turbo.hotwired.dev/handbook/building) document.addEventListener("turbo:load", function () { Gleap.getInstance().softReInitialize(); }); // Depending on your stack, you might need to add the following eventlistener. document.addEventListener("turbolinks:before-render", function () { Gleap.getInstance().softReInitialize(); }); ``` ### Screenshot rendering issues If you are facing any screenshot rendering issues, there are a few different action items you could try right away. We have written a complete help page that you can [find here](rendering-issues). ## 🤝 Need help? We are here to help! [hello@gleap.io](mailto:hello@gleap.io) # AI Agent UI component Source: https://docs.gleap.io/documentation/javascript/ai-agents-ui-component Embed an AI agent conversation directly into your web app. Choose the level of control that fits your needs — drop-in component, headless state manager, or a single API call. ## Drop-in component One HTML tag, everything handled — input, streaming, scrolling. ```html theme={null} ``` With context and a custom placeholder: ```html theme={null} ``` ### Attributes | Attribute | Type | Default | Description | | ---------------- | ------------- | ----------------------------- | -------------------------------------- | | `agentId` | string | **required** | The agent ID | | `conversationId` | string | — | Resume an existing conversation | | `context` | string (JSON) | — | Additional context passed to the agent | | `placeholder` | string | `"Type a message..."` | Input placeholder | | `emptyText` | string | `"How can I help you today?"` | Empty-state text | | `agentColor` | string | primary color | Override accent color | | `dark` | boolean | false | Dark mode | ### Events The component dispatches DOM events you can listen to: ```js theme={null} const el = document.querySelector("gleap-agent-conversation"); el.addEventListener("gleap-agent-conversation-created", (e) => { /* e.detail */ }); el.addEventListener("gleap-agent-message-sent", (e) => { /* e.detail */ }); el.addEventListener("gleap-agent-reply-received", (e) => { /* e.detail */ }); el.addEventListener("gleap-agent-error", (e) => { /* e.detail */ }); ``` The same events also fire on `Gleap.on(...)` without the `gleap-` prefix: ```js theme={null} Gleap.on("agent-reply-received", (data) => { /* ... */ }); Gleap.on("agent-error", (data) => { /* ... */ }); Gleap.on("agent-conversation-created", (data) => { /* ... */ }); ``` *** ## Headless with `Gleap.createAgentChat()` Manage state and streaming yourself, render any UI you want. ```js theme={null} const chat = Gleap.createAgentChat({ agentId: "YOUR_AGENT_ID", context: { page: "/billing" }, onChange: ({ messages, isExecuting, error, conversationId }) => { renderMessages(messages); toggleSpinner(isExecuting); }, }); chat.sendMessage("What is my current plan?"); ``` **Options** * `agentId` – the agent to talk to (defaults to `"kai"`). * `context` – arbitrary object passed to the agent. * `conversationId` – resume an existing conversation. * `onChange({ messages, isExecuting, error, conversationId })` – called whenever state changes. * `onToken`, `onReplyReceived`, `onError`, `onConversationCreated` – optional lifecycle callbacks. **Returned instance** * `sendMessage(content)` – send a user message (streams the reply). * `setContext(context)` – update the context for future messages. * `clearMessages()` – clear messages and start a new conversation. * `cancelStream()` – abort the in-flight stream. * `getState()` – `{ messages, isExecuting, error, conversationId }`. * `destroy()` – tear down listeners. Always call when unmounting. Each message is `{ id, role, content, createdAt, isStreaming? }`. `isStreaming` is `true` while tokens are still arriving. To clear cached conversation state across the page (e.g. on logout): ```js theme={null} Gleap.clearAgentConversation(); ``` *** ## Raw API One call, you handle everything else. ```js theme={null} const result = await Gleap.sendAgentMessage("YOUR_AGENT_ID", "Hello!", { conversationId: previousConversationId, additionalContext: { page: "/billing" }, onToken: (data) => { /* progressive streaming */ }, }); console.log(result.response); // full reply console.log(result.conversationId); // for follow-up calls ``` Returns a Promise that resolves to `{ runId, status, response, conversationId }`. *** ## Custom styling The drop-in component renders inside an iframe and accepts `agentColor` / `dark` for basic theming. For full control over the UI, use the headless `createAgentChat()` API and render your own components. # AI chatbar Source: https://docs.gleap.io/documentation/javascript/aichatbar The AI chatbar is an inline assistant that lets visitors ask questions on any page. It appears automatically once the SDK is initialized. AI chatbar ## `Gleap.showAiChatbar()` Show the chatbar. ```js theme={null} Gleap.showAiChatbar(); ``` ## `Gleap.hideAiChatbar()` Hide the chatbar. ```js theme={null} Gleap.hideAiChatbar(); ``` ## `Gleap.setAiChatbarQuickActions(quickActions)` Set the suggested action buttons shown above the input. ```js theme={null} Gleap.setAiChatbarQuickActions([ "How do I reset my password?", "Contact support", "Check system status", ]); ``` ## `Gleap.setAiChatbarPlaceholder(placeholder)` Override the input placeholder text. ```js theme={null} Gleap.setAiChatbarPlaceholder("Ask about billing..."); ``` ## Customizing the appearance The chatbar renders inside a [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM) for style isolation. Override styles from outside using CSS `::part()`. The host element has class `gleap-ai-ui-widget`. | Part | Description | | ------------------ | ----------------------------------- | | `container` | Outermost container | | `input-container` | Wrapper around the input field | | `input-background` | Blurred background behind the input | | `input` | The `` text field | | `send-button` | The send button | | `quick-actions` | The quick actions row | ```css theme={null} .gleap-ai-ui-widget::part(input-background) { background: #1a1a1a; } .gleap-ai-ui-widget::part(input) { color: #ffffff; font-size: 14px; } .gleap-ai-ui-widget::part(send-button) { background: #6c47ff; } ``` # Frontend tools Source: https://docs.gleap.io/documentation/javascript/aitools Frontend tools let your AI agent execute actions directly inside your app or website — initiating a transfer, resetting a password, cancelling an order, etc. Tools are defined on your AI agent in the Gleap dashboard (**AI agent > Tools > Frontend tool**) — name, description, parameters and execution mode all live there. Your app only registers a handler that executes the tool. Learn how to set up Frontend tools in our [help center article](https://help.gleap.io/en/articles/221-frontend-tools-let-the-ai-run-actions-in-your-app). ## `Gleap.registerAgentTool(name, handler)` Register the handler for a dashboard-defined Frontend tool. Use the tool's runtime name shown in the tool editor. ```js theme={null} Gleap.registerAgentTool("send-money", async ({ amount, contact }) => { // Run your own logic here. // Return a string or JSON — the AI waits for this response. return "The transfer was initiated. The user must confirm it in the banking app."; }); ``` **Handler contract** * The handler receives the parameters configured in the dashboard, filled with the values the AI collected. * Return a string or a JSON-serializable object (objects are stringified). The result is sent back to the AI, which uses it to reply. * Async handlers are fully supported — the AI waits for the returned promise. * Thrown errors are caught and reported to the AI automatically. * If no handler is registered for a tool, the AI is informed so it can respond accordingly. ## Execution modes Set per tool in the dashboard: * `Auto` — the handler runs immediately when the AI calls the tool. * `Ask before final execution` — the AI adds a confirmation button to its reply; the handler only runs after the user confirms. ## Migrating from `setAiTools` `Gleap.setAiTools(tools)` and `Gleap.registerAgentToolAction(callback)` are deprecated. Tools defined via `setAiTools` could only return a static response to the AI — Frontend tools execute real code and return live results. Define your tools on the AI agent in the dashboard and register their handlers via `Gleap.registerAgentTool(name, handler)` instead. # Audio recording Source: https://docs.gleap.io/documentation/javascript/audio-recording Available starting from version 14.2.0. Gleap allows users to record audio messages when chatting with support through our JavaScript SDK. This is a great way to collect feedback from users. ## Enable the audio recording feature To enable the audio recording feature, navigate to `AI chatbot` -> `Settings` and toggle the `Allow audio messages` switch. # Checklists Source: https://docs.gleap.io/documentation/javascript/checklists Dive into a completely refreshed onboarding experience that will guide your users with gusto. The new checklist feature not only ensures your users are thoroughly onboarded but also keeps them deeply engaged. All of this is neatly packed inside our Gleap widget! ## Open the checklists overview Open the checklists overview with the method below. ```js theme={null} Gleap.openChecklists(); ``` ## Manually start a checklist Checklists can be sent either through trigger rules or manually with the method below. ```js theme={null} Gleap.startChecklist("outboundId"); ``` You can find the outboundId within the checklist editor. Please note that SDK version 12.1.0 or higher is required to send checklists. ## Start a checklist from a link or button If you want a checklist to start when someone clicks a link or a button, you can use a `gleap://` link instead of writing any JavaScript. Gleap picks these links up automatically wherever the SDK is loaded: ```html theme={null} Start checklist ``` Replace `OUTBOUND_ID` with the outboundId from the checklist editor. The same format works for other Gleap content: ```html theme={null} Start product tour Open survey Open help article Open news article ``` Because it is a plain link, you can also paste it into the link field of any rich text editor — including help center articles — rather than adding a script. Unlike product tours, checklists have no `gleap_checklist` URL parameter. Use the `gleap://checklist/...` link above to start a checklist from a click. ## Get checklist data Retrieve checklist data programmatically using the checklist ID and project identifier. ```js theme={null} Gleap.getChecklistData("outboundId", "sharedKey").then((data) => { console.log(data); }); ``` The sharedKey is optional. ## Listen for checklist events You can listen to various checklist events to track user progress and interactions. ### Checklist loaded event ```js theme={null} Gleap.on('checklist-loaded', (data) => { console.log('Checklist loaded:', data); }); ``` ### Step completed event ```js theme={null} Gleap.on('checklist-step-completed', (data) => { console.log('Step completed:', data.stepId); }); ``` ### Checklist completed event ```js theme={null} Gleap.on('checklist-completed', (data) => { console.log('Checklist completed!'); }); ``` # Checklist UI component Source: https://docs.gleap.io/documentation/javascript/checklists-ui-component We have designed ready to use components for Gleap checklists. You can directly embed those components into your web-apps, which makes them super powerful and increases checklist usage for onboardings a lot.