# Popp AI Documentation > Documentation for Popp AI ## Guides - [API Key Management](https://docs.joinpopp.com/docs/api-key-management.md) - [Quickstart](https://docs.joinpopp.com/docs/quickstart.md): Get up and running with the Popp API. - [Campaigns](https://docs.joinpopp.com/docs/campaigns-guide.md) - [Job Application Flow](https://docs.joinpopp.com/docs/applicant-outreach-flow.md) - [Document Collection Flow](https://docs.joinpopp.com/docs/document-collection-flow.md) - [Conversations](https://docs.joinpopp.com/docs/conversations-guide.md) - [Documents](https://docs.joinpopp.com/docs/documents-guide.md) - [Analysis](https://docs.joinpopp.com/docs/analysis-guide.md) - [Scheduling](https://docs.joinpopp.com/docs/scheduling-overview.md) - [Meeting Templates](https://docs.joinpopp.com/docs/meeting-templates.md) - [Scheduling Campaigns](https://docs.joinpopp.com/docs/scheduling-campaigns.md) - [Auto-Schedule Conversations](https://docs.joinpopp.com/docs/auto-schedule-conversations.md) - [Scheduling with Availability Collection](https://docs.joinpopp.com/docs/scheduling-with-availability-collection.md) - [Workflow Builder](https://docs.joinpopp.com/docs/workflow-builder-guide.md) - [Workflow Configuration](https://docs.joinpopp.com/docs/workflow-configuration.md) - [Webhooks](https://docs.joinpopp.com/docs/webhooks.md) - [Webhook Event Structure](https://docs.joinpopp.com/docs/webhook-event-structure.md) - [Webhook Authentication with SHA256](https://docs.joinpopp.com/docs/webhook-authentication.md) - [Conversation Events](https://docs.joinpopp.com/docs/conversation-events.md) - [Analysis Events](https://docs.joinpopp.com/docs/analysis-events.md) - [Scheduling Events](https://docs.joinpopp.com/docs/scheduling-events.md) - [Workflow Events](https://docs.joinpopp.com/docs/workflow-events.md) - [Webhook Management](https://docs.joinpopp.com/docs/webhook-management.md) - [Authentication](https://docs.joinpopp.com/docs/authentication-guide.md) - [MCP](https://docs.joinpopp.com/docs/mcp.md) ## API Reference - [Create conversation](https://docs.joinpopp.com/reference/create-conversation.md): Creates a conversation in Popp application - [List conversations](https://docs.joinpopp.com/reference/list-conversations.md): List all conversations in Popp application - [Get conversation](https://docs.joinpopp.com/reference/get-conversation.md): Get a conversation - [List conversation messages](https://docs.joinpopp.com/reference/list-conversation-messages.md): List all messages in a conversation - [Send Conversation Message](https://docs.joinpopp.com/reference/send-conversation-message.md): Send a message as the user/recruiter on a conversation - [Takeover Conversation](https://docs.joinpopp.com/reference/takeover-conversation.md): Take over a conversation from the AI agent so a human can respond directly - [Hand Conversation to Agent](https://docs.joinpopp.com/reference/hand-conversation-to-agent.md): Hand the conversation back to the AI agent after a human takeover - [Bulk create conversations](https://docs.joinpopp.com/reference/bulk-create-conversations.md): Creates multiple conversations in bulk for a single campaign - [Get campaign](https://docs.joinpopp.com/reference/get-campaign.md): Get a campaign - [Create Campaign](https://docs.joinpopp.com/reference/create-campaign.md): Creates a campaign in Popp application. - [List campaigns](https://docs.joinpopp.com/reference/list-campaigns.md): List all campaigns in Popp application - [Generate Questions](https://docs.joinpopp.com/reference/generate-questions.md): Generates interview questions from a job description using Popp agent - [Stop Campaign](https://docs.joinpopp.com/reference/stop-campaign.md): Stops a campaign and optionally sends a cancellation message to candidates - [Update Campaign](https://docs.joinpopp.com/reference/update-campaign.md): Updates an existing campaign. All fields are optional but at least one must be provided. Questions cannot be updated after creation. Setting campaignStatus to ARCHIVED will stop the campaign. Setting campaignStatus to LIVE will activate a DRAFT campaign. - [Get document](https://docs.joinpopp.com/reference/get-document.md): Get a document - [List conversation documents](https://docs.joinpopp.com/reference/list-conversation-documents.md): List documents in a conversation - [Get document media](https://docs.joinpopp.com/reference/get-document-media.md): Get the media of a document - [Download media](https://docs.joinpopp.com/reference/download-media.md): Download the content of a media - [Process Document (Beta)](https://docs.joinpopp.com/reference/process-document.md): **Beta** — endpoint shape and validation rules may evolve before general availability. Classify and validate an uploaded document against a caller-supplied document type definition. Stateless: every call carries the full document type config inline; no organisation-level catalogue lookup is performed. A stateful variant that resolves by `documentTypeId` is planned. - [List document types (Beta)](https://docs.joinpopp.com/reference/list-document-types.md): **Beta:** this endpoint is still in active development; response shape and filter behaviour may change. Searches the document types for the caller's organization. Backed by OpenSearch — supports prefix match on `name`, exact match on `externalId`, and boolean filters on `isArchived` and `isUsedInCampaign`. Results are sorted by `createdAt` (newest first). - [Create a document type (Beta)](https://docs.joinpopp.com/reference/create-document-type.md): **Beta:** this endpoint is still in active development; payload shape and validation rules may change. Creates a document type in the caller's organization. The name is required; everything else is optional. `externalId` must be unique per organization. `validationSettings` is a JSON-encoded string whose only recognised keys today are `validFor` and `issuedAfter` (each `{ "value": number, "unit": "DAYS"|"MONTHS"|"YEARS" }`). Once created, reference the returned `id` from a Campaign `DOCUMENT` question via `documentItems: [{ documentTypeId }]`. The server populates a readable `documentTypeName` copy on each reference so the Campaign payload is greppable without a join. See `POST /v1/campaigns` for the per-question shape. - [Get a document type by ID (Beta)](https://docs.joinpopp.com/reference/get-document-type.md): **Beta:** this endpoint is still in active development; response shape may change. Fetches a single document type by its ID. Returns 404 if the document type does not exist or belongs to a different organization. - [Update a document type (Beta)](https://docs.joinpopp.com/reference/update-document-type.md): **Beta:** this endpoint is still in active development; payload shape and validation rules may change. Partially updates a document type. Pass only the fields you want to change. To clear a nullable field send an explicit `null`. Constraints: - Cannot update an archived document type (returns 409). Restore is not supported — create a new one. - The `name` cannot be changed while the document type is referenced by a campaign or workflow (returns 409). Other fields can still be edited. - `externalId` must be unique per organization. - [Delete a document type (Beta)](https://docs.joinpopp.com/reference/delete-document-type.md): **Beta:** this endpoint is still in active development. Hard-deletes a document type. Rejected with 409 if the document type is referenced by any campaign or workflow — archive it instead. Use this only to undo a mistaken create. - [Archive a document type (Beta)](https://docs.joinpopp.com/reference/archive-document-type.md): **Beta:** this endpoint is still in active development. Soft-deletes a document type by setting `isArchived: true`. Idempotent — archiving an already-archived document type returns 200 with the existing record. Historical references from past campaigns and workflows are preserved. - [Get organization](https://docs.joinpopp.com/reference/get-organization.md): Get an organization - [List templates](https://docs.joinpopp.com/reference/list-templates.md): List all message templates belonging to the authenticated organization - [List agents](https://docs.joinpopp.com/reference/list-agents.md): List all agents belonging to the authenticated organization - [List Webhooks](https://docs.joinpopp.com/reference/list-webhooks.md): List all webhooks configured for the organization - [Create Webhook](https://docs.joinpopp.com/reference/create-webhook.md): Create a new webhook for the organization. - [Update Webhook](https://docs.joinpopp.com/reference/update-webhook.md): Update an existing webhook configuration - [Delete Webhook](https://docs.joinpopp.com/reference/delete-webhook.md): Delete a webhook configuration - [List Webhook Events](https://docs.joinpopp.com/reference/list-webhook-events.md): List all webhook event types available for subscription, with their descriptions and categories - [Get organization configuration](https://docs.joinpopp.com/reference/get-organization-config.md): Get an organization configuration - [Create Organization Config](https://docs.joinpopp.com/reference/create-organization-config.md): Creates an Organization Config - [Update organization configuration](https://docs.joinpopp.com/reference/update-organization-config.md): Updates an organization configuration - [Create analysis candidate](https://docs.joinpopp.com/reference/create-analysis-candidate.md): Creates an analysis candidate - [Generate requirements](https://docs.joinpopp.com/reference/generate-requirements.md): Uses AI to extract requirements from a job description. Stateless - does not create or modify any data. - [Create analysis](https://docs.joinpopp.com/reference/create-analysis.md): Creates a new analysis with the given title, job description, and requirements. Immediately starts processing. - [List analyses](https://docs.joinpopp.com/reference/list-analyses.md): List all analyses for the organization with optional filtering - [Get analysis](https://docs.joinpopp.com/reference/get-analysis.md): Get a single analysis with full requirements - [Update analysis](https://docs.joinpopp.com/reference/update-analysis.md): Update analysis metadata (title, job description, external ID). Does not update requirements. - [Archive analysis](https://docs.joinpopp.com/reference/archive-analysis.md): Archives an analysis (soft delete). Only DRAFT or LIVE analyses can be archived. Archiving an already-archived analysis is idempotent. - [Update requirements and reanalyse](https://docs.joinpopp.com/reference/update-requirements-and-reanalyse.md): Replaces all requirements on the analysis and triggers re-analysis of existing candidates. Requirements with an ID are updated, without an ID are created, and existing requirements not in the array are deleted. Only DRAFT or LIVE analyses can be updated. - [Create auto-schedule conversation](https://docs.joinpopp.com/reference/create-scheduling-conversation.md): Creates a scheduling conversation in Popp application. This endpoint is used for meeting scheduling workflows where participants can provide their availability and a meeting will be scheduled automatically. - [Invite Calendar Contact](https://docs.joinpopp.com/reference/invite-calendar-contact.md): Invites an external contact to connect their calendar. This sends an invitation to the contact allowing them to share their calendar availability. - [List meeting templates](https://docs.joinpopp.com/reference/list-meeting-templates.md): Search and list meeting templates belonging to the authenticated organization. All search filters are optional. Results are always scoped to the authenticated organization. **Note:** For full meeting template details (including configuration options like buffer, reminder settings, and availability), use the `/v1/meeting-templates/{templateId}` endpoint. - [Get meeting template](https://docs.joinpopp.com/reference/get-meeting-template.md): Get full details of a meeting template by ID. Returns the complete meeting template configuration including availability settings, buffer times, reminder settings, and participant information. Use this endpoint when you need the full configuration details. For a list overview of meeting templates, use the `/v1/meeting-templates` endpoint instead. Returns 404 if the template does not exist, or if it belongs to a different organisation than the one tied to the API key. - [Create Meeting Template](https://docs.joinpopp.com/reference/create-meeting-template.md): Creates a calendar meeting template for scheduling meetings. The template defines meeting parameters such as duration, participants, availability, and video conferencing settings. - [Resend booking URL](https://docs.joinpopp.com/reference/resend-booking-url.md): Resends a booking URL to an existing conversation with updated meeting configuration. Use this when a candidate cannot find suitable time slots and you need to provide new availability options. Identify the conversation using either conversationId or externalConversationId. You can either reference an existing meeting template or create a new one with custom configuration. - [Update Meeting Template](https://docs.joinpopp.com/reference/update-meeting-template.md): Updates a calendar meeting template by ID. Replaces the meeting configuration with the provided payload (full replacement semantics — every field that should be present on the resulting template must be supplied). Returns 404 if the template does not exist, or if it belongs to a different organisation than the one tied to the API key. - [Delete Meeting Template](https://docs.joinpopp.com/reference/delete-meeting-template.md): Deletes a calendar meeting template by ID. Returns 404 if the template does not exist, or if it belongs to a different organisation than the one tied to the API key. Returns 409 Conflict if the template is referenced by an active campaign or has scheduled future bookings. - [Update Booking](https://docs.joinpopp.com/reference/update-booking.md): Update an existing booking. Supports updating the title, time, duration, description, location, and attendees of the meeting. The underlying calendar event is updated and participants are notified by default. Cannot be used on cancelled bookings or to set a start time in the past. Returns 404 if the booking does not exist, or if it belongs to a different organisation than the one tied to the API key. - [Get a calendar booking](https://docs.joinpopp.com/reference/get-booking.md): Get full details of a calendar booking by ID. Returns the booking record only if it belongs to the authenticated organization. - [List calendar bookings](https://docs.joinpopp.com/reference/list-bookings.md): List calendar bookings belonging to the authenticated organization. All filters are optional. Results are always scoped to the authenticated organization. Results are paginated using a cursor (`nextToken`). To fetch the next page, pass the `nextToken` from the previous response back as a query parameter. - [Cancel Booking](https://docs.joinpopp.com/reference/cancel-booking.md): Cancel an existing booking. The underlying calendar event is cancelled via Nylas and a cancellation notification is sent to all participants by default. Returns 404 if the booking does not exist, or if it belongs to a different organisation than the one tied to the API key. Returns 409 if the booking has already been cancelled. Returns 400 if the booking has already started. - [Parse Availability](https://docs.joinpopp.com/reference/parse-availability.md): Parses natural-language availability text into structured time slots. Supports multi-turn clarification via the messages array. Does NOT save the availability — call PUT /v1/user-calendars/{userCalendarId}/availability after the user confirms. - [Set User Calendar Availability](https://docs.joinpopp.com/reference/set-user-calendar-availability.md): Saves confirmed availability time slots to a participant's virtual calendar. Once all required participants for a meeting have availability recorded, the scheduling link is generated and sent to the candidate automatically. - [List User Calendars](https://docs.joinpopp.com/reference/list-user-calendars.md): List user calendars connected to the requesting organization. Use this to discover the `userCalendarId` needed to publish availability via PUT /v1/user-calendars/{userCalendarId}/availability. - [Get User Calendar](https://docs.joinpopp.com/reference/get-user-calendar.md): Fetch a single user calendar by id. Returns 404 if the calendar does not exist or does not belong to the requesting organization (the API does not leak existence across organizations). - [Create workflow](https://docs.joinpopp.com/reference/create-workflow.md): Creates a new workflow in the UNPUBLISHED state. The workflow cannot accept runs until it has been successfully published. See the Workflow Configuration guide for the configuration JSON schema. - [List workflows](https://docs.joinpopp.com/reference/list-workflows.md): Returns a paginated list of workflows for the authenticated organization, ordered by `updatedAt` descending. Use `nextToken` to page through results. - [Get workflow](https://docs.joinpopp.com/reference/get-workflow.md): Returns a workflow by ID, including its full `configuration` and `settings` JSON strings. - [Update workflow](https://docs.joinpopp.com/reference/update-workflow.md): Updates the working draft of a workflow. At least one field must be provided. Updates do not affect runs already in flight against the previously-published version — call publish to make changes live. - [Get workflow by external ID](https://docs.joinpopp.com/reference/get-workflow-by-external-id.md): Returns a workflow looked up by its caller-supplied external ID. External IDs are unique within an organization. - [Update workflow by external ID](https://docs.joinpopp.com/reference/update-workflow-by-external-id.md): Updates the working draft of a workflow looked up by its caller-supplied external ID. At least one field must be provided. - [Get candidate profile by external ID](https://docs.joinpopp.com/reference/get-candidate-profile-by-external-id.md): Returns the candidate profile in the caller's organization group with the given external ID. Returns 404 when no profile matches. - [Publish workflow by external ID](https://docs.joinpopp.com/reference/publish-workflow-by-external-id.md): Publishes the working draft of a workflow looked up by its caller-supplied external ID. - [Archive workflow by external ID](https://docs.joinpopp.com/reference/archive-workflow-by-external-id.md): Marks a workflow looked up by its caller-supplied external ID as archived. - [Pause workflow by external ID](https://docs.joinpopp.com/reference/pause-workflow-by-external-id.md): Pauses a published workflow looked up by its caller-supplied external ID. - [Resume workflow by external ID](https://docs.joinpopp.com/reference/resume-workflow-by-external-id.md): Returns a paused workflow looked up by its caller-supplied external ID to PUBLISHED state. - [Start workflow runs by external ID](https://docs.joinpopp.com/reference/start-workflow-runs-by-external-id.md): Enrols one or more candidates into a published workflow looked up by its caller-supplied external ID. Enrolment is asynchronous — every accepted entry is enqueued and its run is created downstream, so runs are not returned inline. Inspect `summary` for the rollup and `errors[]`, `alreadyEnrolled[]`, `duplicatesInRequest[]` for per-entry dispositions. - [Publish workflow](https://docs.joinpopp.com/reference/publish-workflow.md): Validates and publishes the working draft of a workflow. On success (200) the new version becomes live and can accept runs. If the configuration fails validation the workflow is left unchanged and the call returns a 400 error whose message lists the problems — validation failures are not a 200 response. Beyond configuration validation, publish also returns a 400 when an ATS entry pathway names a job already connected to another workflow, campaign, or analysis (`ATS_JOB_ALREADY_CONNECTED`), or when automatic rubric generation for a screening node fails (`RUBRIC_GENERATION_FAILED`). - [Archive workflow](https://docs.joinpopp.com/reference/archive-workflow.md): Marks a workflow as archived. Archived workflows cannot be edited, published or used to start new runs. In-flight runs at the time of archive continue to completion. - [Pause workflow](https://docs.joinpopp.com/reference/pause-workflow.md): Pauses a published workflow. Paused workflows reject new runs but let in-flight runs complete. Resume the workflow to accept new runs again. - [Resume workflow](https://docs.joinpopp.com/reference/resume-workflow.md): Returns a paused workflow to PUBLISHED state, allowing new runs to start. - [Start workflow runs](https://docs.joinpopp.com/reference/start-workflow-runs.md): Enrols one or more candidates into a published workflow. Provide candidates by ID, by external ID, or as inline contacts (combined cap of 5000). Enrolment is asynchronous — every accepted entry is enqueued and its run is created downstream, so runs are not returned inline. Inspect `summary` for the rollup and `errors[]`, `alreadyEnrolled[]`, `duplicatesInRequest[]` for per-entry dispositions; per-entry failures never fail the whole call. - [List workflow runs](https://docs.joinpopp.com/reference/list-workflow-runs.md): Returns a paginated list of runs for the given workflow. Filter by status and/or candidate profile. - [Get workflow run](https://docs.joinpopp.com/reference/get-workflow-run.md): Returns a workflow run by ID, including its full `context` JSON string. - [Cancel workflow run](https://docs.joinpopp.com/reference/cancel-workflow-run.md): Cancels an in-flight workflow run. By default any active conversation is left to complete naturally; pass `closeActiveConversations: true` in the body to close it as part of the cancellation. - [List ATS jobs](https://docs.joinpopp.com/reference/list-ats-jobs.md): Returns a paginated list of the authenticated organization's ATS jobs, read live from your connected ATS and annotated with what each job is connected to in Popp (`workflow`, `campaign`, or `analysis`). Each job includes the available detail — `description` (which may contain HTML), location, salary, employment type, screening questions, hiring-pipeline stages, and any ATS custom fields. Use this to discover the `atsJobId` you need to wire an ATS entry pathway when building an ATS-driven workflow. Results are cursor-paginated — pass the returned `next` value back as the `next` query parameter to fetch the following page. Filtering by a single `atsJobId` still returns an array — of length 0 or 1, never a bare object or a 404. Returns `502` if the ATS integration returns an error. - [List ATS job stages](https://docs.joinpopp.com/reference/list-ats-job-stages.md): Returns the interview pipeline stages for a single ATS job, read live from your connected ATS. Discover the `atsJobId` via [`GET /v1/ats/jobs`](/docs/list-ats-jobs). Returns `502` if the ATS integration returns an error. An empty `stages` list means the job has none configured. - [List ATS rejection reasons](https://docs.joinpopp.com/reference/list-ats-rejection-reasons.md): Returns the rejection reasons configured in the authenticated organization's connected ATS, read live. Use the `atsReasonId` values when configuring workflow behaviour that rejects a candidate in the ATS. Returns `422` if your connected ATS does not support rejection reasons, or `502` if the ATS integration returns an error. An empty `rejectionReasons` list means none are configured.