Skip to main content

Draft replies for your support team in Salesforce

In this tutorial, you build a set of Salesforce flows that draft a reply to every new case and every new customer email. Kapa indexes your knowledge sources, such as your documentation site, Notion, Confluence, GitHub, PDFs, and past Salesforce Cases, into one searchable knowledge base. The flows send each customer message to Kapa's Chat API and add the answer to the case as an internal comment. By the time an agent opens the case, the draft is already there, ready to edit and send or to discard.

Everything happens inside Salesforce Setup and Flow Builder, with no Apex code and nothing extra to host. You decide exactly when Kapa is called and where its answer goes, and a person always decides what reaches the customer.

To answer customers before they open a case at all, add the Support Form Deflector, which works with Salesforce Service Cloud and answers on your support form before the case is filed. This tutorial covers the cases that still come in.

By the end of this tutorial, you will have:

  • A named credential that stores your Kapa API key.
  • A reusable subflow that sends a message to Kapa and posts the drafted reply as an internal case comment.
  • Two trigger flows that call the subflow: one for new web and portal cases, one for every inbound customer email.
note

This guide is accurate as of 16 October 2026. Salesforce updates Setup and Flow Builder several times a year, so some menu names or locations in your org may differ from the ones described here.

Before you start​

You need:

  • A Kapa project whose indexed knowledge sources contain the knowledge you want the drafts to draw from. Because every draft passes through a human before anything reaches the customer, internal sources (runbooks, internal wikis, and past tickets through the Salesforce Cases connector) are as useful here as public documentation.
  • A Salesforce org on Enterprise, Performance, Unlimited, or Developer Edition, which are the editions that include Flow HTTP callouts.
  • Salesforce admin access (the System Administrator profile), to create credentials, fields, permission sets, and flows.

Build and test in a sandbox or Developer Edition org first, then move the setup to production.

How it works​

How the Salesforce flows draft a reply with KapaSALESFORCENew caseweb form or portalInbound emailfirst email or replyrecord-triggered flows,async pathKapa: Draft Case Replysubflow · inputs: CaseId, QueryGet Caseread thread IDThread IDon case?noyesStart threadPOST /projects/{id}/chat/Continue threadPOST /threads/{id}/chat/queryquerykey sent as X-API-KEYby the named credentialKAPAChat APIapi.kapa.aianswer, thread_id200 OK?nono draftyesPost draftprivate Case CommentSave thread IDnew threads onlydraftSupport agentedits and sends

Two trigger flows hand the case ID and the customer's message to one subflow. On a case's first message, the subflow starts a Kapa thread and saves its ID on the case; on every later message, it continues that thread, so Kapa sees the whole conversation. When Kapa answers, the subflow posts the answer as a private case comment for your agent. Each trigger flow fires once per new case or new inbound email, so each customer message gets one draft.

Get your Kapa credentials​

The Salesforce side needs three values from the Kapa platform:

  1. Project ID: the unique identifier of your Kapa project. Go to Settings > Projects and copy it from the table.
  2. Integration ID: navigate to Integrations (under Deploy in the sidebar), click Add new integration, choose HTTP API, and copy the new integration's ID. Kapa uses it to label the drafting conversations, so they show up separately in the dashboard and in Analytics.
  3. API key: navigate to API Keys (under Deploy in the sidebar), click Add new API key, and copy the key.

Keep these three values handy. You paste them into Salesforce in the next sections.

Store your API key in a named credential​

Salesforce keeps API credentials in an external credential. A named credential pairs it with the Kapa API's URL, and flows call Kapa through the named credential, so they never see the key itself.

How a Salesforce flow sends your Kapa API keySALESFORCEHTTP calloutin the subflowcallsNAMED CREDENTIALKapahttps://api.kapa.aiusesEXTERNAL CREDENTIALKapa_APIPRINCIPALKapaApiKey = your keyHEADERX-API-KEY= ApiKeywith keyKAPAChat APIapi.kapa.airuns asRunning userscreated the case or emailassigned toPERMISSION SETKapa API Accessgrants access

You set up three pieces: the external credential that holds the key and adds it as the X-API-KEY header, the named credential that the flows call, and a permission set that lets the users the flows run as use the credential. If the user a flow runs as does not have the permission set, the callout fails with "We couldn't access the credential(s)".

All Setup steps in this tutorial use the full Setup menu: click the gear icon in the top right, choose Setup, and find each page by name in the Quick Find box.

Create the external credential​

  1. In Setup, go to Named Credentials and open the External Credentials tab. Click New.

  2. Configure it:

    • Label: Kapa API
    • Name: Kapa_API
    • Authentication Protocol: Custom
  3. Save. Under Principals, click New:

    • Parameter Name: Kapa
    • Identity Type: Named Principal
    • Under Authentication Parameters, click Add and create a parameter named ApiKey, with your Kapa API key as the value.
  4. Save. Under Custom Headers, click New:

    • Name: X-API-KEY
    • Value: {!$Credential.Kapa_API.ApiKey}

    Kapa rejects requests that send the key under Authorization or any other header name.

Create the named credential​

  1. Go back to Named Credentials and click New on the Named Credentials tab.
  2. Configure it:
    • Label: Kapa
    • Name: Kapa
    • URL: https://api.kapa.ai
    • Enabled for Callouts: checked
    • External Credential: Kapa API
    • Allow Formulas in HTTP Header: checked. Without it, Salesforce sends the formula text instead of your key.
  3. Save.

Give users access to the credential​

A flow can only use the credential when the user it runs as has access to it. The part of the flow that calls Kapa runs as the user who created the case or email, so each of those users needs access. Depending on how your org is set up, they are typically:

Where the message comes fromUser who creates the case or email
Web formThe user Web-to-Case runs as
EmailThe user Email-to-Case runs as
PortalYour Experience Cloud customer users, and the site's guest user if visitors can open cases without logging in
Cases created by hand, for example while testingYou and your support agents

To confirm for your org, open a case from each channel and check its Created By field. On a case with customer emails, also open an inbound email from the Emails related list and check its Created By field.

  1. In Setup, go to Users > Permission Sets and click New. Set Label to Kapa API Access, leave License as --None-- so you can assign it to any user, and save.
  2. On the permission set's page, in the Apps section, click the External Credential Principal Access link.
  3. Click Edit. The button sits in the grey header bar of the External Credential Principal Access table, above the column names.
  4. In Available External Credential Principals, select Kapa_API - Kapa, click the Add arrow to move it to Enabled External Credential Principals, and click Save. The table now lists Kapa_API - Kapa.
  5. Assign the permission set to the users you identified above: on the permission set's page, click Manage Assignments in the button bar at the top, then Add Assignment. Select the users and click Assign.

The external credential itself needs only the one Kapa principal you created earlier. Access is granted here, on the permission set; adding more principals on the external credential page does not give anyone access. The permission set only lets the flow use the key on a user's behalf; users cannot read the key's value.

If Created By shows Automated Process

The Automated Process user has no page to assign permission sets from. Assign the permission set with Data Loader or Workbench instead, by inserting one PermissionSetAssignment record:

  • AssigneeId: the ID of the Automated Process user, from the query SELECT Id FROM User WHERE UserType = 'AutomatedProcess'.
  • PermissionSetId: the ID of the Kapa API Access permission set, from the query SELECT Id FROM PermissionSet WHERE Label = 'Kapa API Access'.

Add a field for the Kapa thread​

Kapa keeps the conversation history for you in a thread. To continue the same thread when the customer replies, store its ID on the case.

  1. In Object Manager, open Case and go to Fields & Relationships. Click New.
  2. Choose Text, and configure it:
    • Field Label: Kapa Thread ID
    • Length: 64
    • Field Name: Kapa_Thread_Id. Salesforce fills in Kapa_Thread_ID from the label; either works, because API names are not case-sensitive.
  3. Click Next through the field-level security step, keeping the defaults. On the page layouts step, uncheck all layouts, because only the flows use this field. Save.

Build the drafting subflow​

The subflow holds all the Kapa logic: it takes a case ID and the customer's message, and posts the draft. The trigger flows only decide when to call it, which is what makes the setup easy to extend to more channels later.

In Setup, go to Process Automation > Flows and click New Flow. Choose Autolaunched Flow (No Trigger). The steps below use Flow Builder's default auto-layout canvas.

Create the resources​

In the Toolbox, click New Resource to create each of these resources:

API nameTypeSettings
CaseIdVariable, TextAvailable for input
QueryVariable, TextAvailable for input
KapaProjectIdConstant, TextYour Kapa project ID
KapaIntegrationIdConstant, TextYour Kapa integration ID
AnswerVariable, TextHolds the drafted reply
NewThreadIdVariable, TextHolds the ID of a newly started thread
AnswerTrimmedFormula, TextLEFT({!Answer}, 3900)
PromptText TemplateSee below
CommentTextText TemplateSee below

Create both text templates with the editor switched to View as Plain Text, so Salesforce does not add HTML tags.

Prompt wraps the customer's message in an instruction:

Suggest a reply to this customer message. Reply with only plaintext. If the message contains quoted earlier emails, reply only to the newest message at the top:

{!Query}

CommentText is the body of the internal comment. Case comments hold at most 4,000 characters, which is why it uses the trimmed answer:

Kapa suggested reply:

{!AnswerTrimmed}

Look up the case​

Add a Get Records element:

  • Label: Get Case
  • Object: Case
  • Condition: Id Equals {!CaseId}
  • How Many Records to Store: Only the first record

Decide whether a Kapa thread exists​

After it, add a Decision element named Has Kapa thread?, with one outcome:

  • Outcome: Continue thread, when {!Get_Case.Kapa_Thread_Id__c} Is Blank False.
  • Default outcome: rename it to Start thread.

Start a new thread​

On the Start thread branch, you first create the HTTP callout action in a wizard, then place it in the flow with the elements that build its request and read its response.

Create the callout action​

  1. On the Start thread branch, add an Action and click Create HTTP Callout.

  2. External service: name it KapaStartThread and select the Kapa named credential. Click Next.

  3. Invocable action:

    • Label: Start Kapa thread
    • Method: POST
    • URL Path: /query/v1/projects/{project_id}/chat/. Set the path variable project_id to type String. Use a path variable here; the path field does not accept the hyphens in your project ID.
  4. Request body: click New, paste this sample, and click Review, then Done:

    {
    "integration_id": "00000000-0000-0000-0000-000000000000",
    "query": "How do I reset my password?"
    }
  5. Response body: click New, choose Use Example Response, paste this sample, and click Review, then Done. It mirrors Kapa's full response, so every field Kapa returns has a place in the generated data structure:

    {
    "answer": "Go to Settings > Security and click Reset password.",
    "thread_id": "00000000-0000-0000-0000-000000000000",
    "question_answer_id": "00000000-0000-0000-0000-000000000000",
    "is_uncertain": false,
    "relevant_sources": [
    {
    "source_url": "https://docs.example.com/security",
    "title": "Security settings",
    "contains_internal_data": false
    }
    ]
    }
  6. Click Save. Salesforce creates the action and returns you to the flow.

Add it to the flow​

  1. Configure the action in the flow:

    • Label: Start Kapa thread, so its API name is Start_Kapa_thread.
    • project_id: {!KapaProjectId}
    • body: click New Resource to create an Apex-defined variable for the request body, named StartBody. Its type is filled in for you.
  2. Fill the request body: click the + on the connector just above the Start Kapa thread action, add an Assignment element named Build start request, and set:

    • {!StartBody.integration_id} Equals {!KapaIntegrationId}
    • {!StartBody.query} Equals {!Prompt}
  3. After the action, add a Decision named Thread started?, with one outcome Yes when {!Start_Kapa_thread.responseCode} Equals 200. On the default outcome, add an End element.

    When Kapa returns an error, the action does not fail: it sets responseCode to the error status and leaves the 2XX output empty, so this check keeps the flow from reading an empty answer.

  4. On the Yes outcome, add an Assignment named Keep start answer that sets:

    • {!Answer} Equals {!Start_Kapa_thread.2XX.answer}
    • {!NewThreadId} Equals {!Start_Kapa_thread.2XX.thread_id}

Continue an existing thread​

On the Continue thread branch, build the same steps with the thread endpoint:

  1. Add an Action and click Create HTTP Callout again:
    • External service: name it KapaContinueThread and select the Kapa named credential.
    • Label: Continue Kapa thread
    • Method: POST
    • URL Path: /query/v1/threads/{thread_id}/chat/, with the path variable thread_id of type String.
    • Use the same request and response samples as for the first action, and click Save.
  2. In the flow, set the action's Label to Continue Kapa thread, so its API name is Continue_Kapa_thread. Set thread_id to {!Get_Case.Kapa_Thread_Id__c}, and body to a new Apex-defined variable named ContinueBody.
  3. Above the action, add an Assignment named Build continue request that sets {!ContinueBody.integration_id} to {!KapaIntegrationId} and {!ContinueBody.query} to {!Prompt}.
  4. After the action, add a Decision named Thread continued?, with one outcome Yes when {!Continue_Kapa_thread.responseCode} Equals 200, and an End element on the default outcome.
  5. On Yes, add an Assignment named Keep continue answer that sets {!Answer} Equals {!Continue_Kapa_thread.2XX.answer}.

Post the draft as an internal comment​

Below the point where the two branches of Has Kapa thread? join, add a Create Records element and configure it:

  1. Label: Post draft
  2. How to set record field values: change it from From a Record Variable to Manually. This lets you set each field of the new comment directly, without first building a record variable.
  3. How Many Records to Create: One
  4. Object: Case Comment
  5. Under Set Field Values for the Case Comment, click + Add Field for each field:
    • ParentId = {!CaseId}
    • IsPublished = {!$GlobalConstant.False}. This keeps the comment internal, visible to your team only. Setting it to True would show Kapa's answer to the customer in your portal; do not do that until you have reviewed enough drafts to trust them.
    • CommentBody = {!CommentText}

The comment's author is the user the flow runs as, for example the customer for a portal case. The Kapa suggested reply heading is what marks it as a draft.

Save the new thread ID​

After Post draft, add a Decision named New thread?, with one outcome Yes when {!NewThreadId} Is Blank False. On it, add an Update Records element named Save thread ID:

  • How to Find Records to Update and Set Their Values: Specify conditions to identify records, and set fields individually
  • Object: Case
  • Filter Case Records: Id Equals {!CaseId}
  • Set Field Values for the Case Records: Kapa_Thread_Id__c = {!NewThreadId}

The case is only updated when a thread starts, so follow-up drafts do not touch the case record.

Before you save, check your canvas against the finished subflow:

The finished Kapa: Draft Case Reply subflow in Flow BuilderStartGet RecordsGet CaseHas Kapa thread?Start threadContinue threadAssignmentBuild start requestAction · HTTP calloutStart Kapa threadThread started?YesEndDefaultAssignmentKeep start answerAssignmentBuild continue requestAction · HTTP calloutContinue Kapa threadThread continued?YesEndDefaultAssignmentKeep continue answerCreate RecordsPost draftNew thread?YesUpdate RecordsSave thread IDDefaultEnd

Save the flow as Kapa: Draft Case Reply and click Activate.

tip

Add a Fault path from each HTTP callout action, for example to an email alert to your Salesforce admin. Kapa's error responses go through the responseCode check, but a timeout or a connection error makes the action itself fail; without a fault path, that only shows up in Salesforce's flow error emails.

Trigger a draft on every new case​

This flow drafts a reply when a case is created through your web form or portal. Cases created from email are left to the inbound email flow; otherwise each email case would get two drafts.

  1. Create a new flow and choose Record-Triggered Flow.
  2. Configure the start:
    • Object: Case
    • Trigger the Flow When: A record is created
    • Entry conditions: Any Condition Is Met (OR), with one condition Origin Equals <value> for each origin your web form and portal set, for example Web. Check the Case Origin field on a case from each channel to find the values your org uses.
    • Optimize the Flow for: Actions and Related Records
    • Check Include a Run Asynchronously path to access an external system after the original transaction for the triggering record is successfully committed.
  3. On the Run Asynchronously path, add a Subflow element that calls Kapa: Draft Case Reply:
    • CaseId: {!$Record.Id}

    • Query: click New Resource and create a Text Template named CaseMessage, in plain text, with this body:

      {!$Record.Subject}

      {!$Record.Description}
  4. Save the flow as Kapa: Draft Reply on New Case and activate it.

Salesforce does not allow calls to external systems on the immediate path of a record-triggered flow. The asynchronous path runs after the case is saved, so saving the case is not slowed down, and the draft appears shortly after, usually within a minute.

Trigger a draft on every inbound email​

This flow drafts a reply for every email a customer sends on a case: the first email that creates an Email-to-Case case, and every reply after it.

  1. Create a new flow and choose Record-Triggered Flow.
  2. Configure the start:
    • Object: Email Message
    • Trigger the Flow When: A record is created
    • Entry conditions: All Conditions Are Met (AND), with:
      • Incoming Equals True. This skips the emails your agents send.
      • ParentId Is Null False. This skips emails that are not attached to a case.
    • Optimize the Flow for: Actions and Related Records
    • Check Include a Run Asynchronously path….
  3. On the Run Asynchronously path, add a Subflow element that calls Kapa: Draft Case Reply:
    • CaseId: {!$Record.ParentId}

    • Query: click New Resource and create a Text Template named EmailText, in plain text, with this body. TextBody is the plain-text version of the email.

      {!$Record.Subject}

      {!$Record.TextBody}
  4. Save the flow as Kapa: Draft Reply on Inbound Email and activate it.

Together, the two trigger flows cover every customer message on a case:

Which trigger flow drafts each customer messageFIRST MESSAGEEACH FOLLOW-UP EMAILWeb form or portal caseOrigin: Web, or your portal's valueCase is createdKapa: Draft Reply on New Casestarts a Kapa thread, saves its IDCustomer replies by emailKapa: Draft Reply on Inbound Emailcontinues the same threadthread IDEmail-to-Case caseOrigin: EmailFirst email creates the caseKapa: Draft Reply on Inbound Emailstarts a Kapa thread, saves its IDCustomer repliesKapa: Draft Reply on Inbound Emailcontinues the same threadthread IDKapa: Draft Reply on New Case does not run:Email is not one of its origin conditions

Tune the drafting style (optional)​

By default, the drafts follow Kapa's standard response style. A customization lets you match them to how your team actually writes. Because the customization is tied to the integration, nothing changes on the Salesforce side.

  1. Navigate to Customizations (under Configure in the sidebar) and create a new customization. Give it a name, for example Salesforce drafts.
  2. Under Style & Tone, click + Add item for each rule the drafts should follow. Each instruction has a name and a description, for example:
    • No salutations: "Do not open with a greeting or close with a sign-off. Return only the body of the reply."
    • Plain text: "Do not use Markdown. Case comments display plain text only."
    • No internal links: "Never include links to internal sources, such as past support cases or internal wiki pages. Use them to inform the answer, but only link public documentation."
  3. Check the preview panel on the right, which shows the system instructions with your changes applied.
  4. In the Integrations selector on the customization, pick your HTTP API integration and save. The association also works the other way around, from the Customization column of the Integrations table.

Every draft the subflow requests now follows these instructions. The third rule is also what makes internal knowledge sources safe to draw on: the model can use a past case to get the answer right without the draft pointing your customer at it. For guidance on writing instructions that models follow reliably, see Write effective instructions.

Verify it works​

  1. Make sure the Case Comments related list is on your case page, so you can see the drafts. If it is missing, add it in Object Manager > Case > Page Layouts.
  2. Submit a test case through your web form or portal with a question your knowledge sources answer. Wait a minute and open the case: a private comment starting with Kapa suggested reply appears under Case Comments.
  3. Send an email to your Email-to-Case address. Check that the new case gets exactly one draft.
  4. On that case, send an email reply to the customer. Then, from the customer's mailbox, reply to that email with a follow-up question. A second draft appears, and it builds on the first answer.

Then open the Conversations page in Kapa and filter by your HTTP API integration to see the drafting traffic.

Limit drafts to specific cases (optional)​

By default, every case and inbound email that matches the trigger flows gets a draft, whoever the case is assigned to. To draft only for some cases, for example one queue, one case type, or one record type, add a filter to the subflow. A filter there applies to every channel at once, including any you add later.

  1. Open the Kapa: Draft Case Reply flow.

  2. Click the + between Get Case and Has Kapa thread?, and add a Decision element named Should Kapa draft?.

  3. Add one outcome named Yes, with the conditions the case must meet. For example:

    • Cases in one queue: {!Get_Case.OwnerId} Equals the queue's ID. Find it in Setup under Users > Queues: open the queue and copy the ID starting with 00G from the page URL.
    • Cases of one type: {!Get_Case.Type} Equals Question.
    • Cases of one record type: {!Get_Case.RecordTypeId} Equals the record type's ID. Find it in Object Manager > Case > Record Types: open the record type and copy the ID starting with 012 from the page URL.

    To combine conditions, set Condition Requirements to Execute Outcome to All Conditions Are Met (AND) or Any Condition Is Met (OR).

  4. On the default outcome, add an End element. Cases that do not match end here, without calling Kapa.

  5. Save the flow as a new version and activate it.

The subflow reads the case after it is saved, so the filter sees the owner your assignment rules set. For follow-up emails, it checks the case as it is when the email arrives: if a case moves to a queue outside the filter, its later emails stop getting drafts.

Cases that do not match never call Kapa, so the users who create them do not need the Kapa API Access permission set.

Extend to more channels​

The subflow works the same no matter where a message comes from. To draft replies for another channel, add one more record-triggered flow that calls Kapa: Draft Case Reply on its asynchronous path with the case ID and the message text, and give the users who create those records the Kapa API Access permission set. For example, to draft replies when a customer adds a comment on a case in your portal:

  • Object: Case Comment, when a record is created.
  • Entry conditions: IsPublished Equals True. The drafts themselves are private comments, so they never trigger this flow.
  • Add a Decision that checks {!$Record.CreatedBy.IsPortalEnabled} Equals True, so comments from your own agents are skipped.
  • Subflow inputs: CaseId = {!$Record.ParentId}, Query = {!$Record.CommentBody}.

Move the setup to production​

Once the flows work in your sandbox, move them with a change set or your usual deployment tool. Include the Kapa_Thread_Id__c field, the Kapa API Access permission set, the external credential and named credential, the two external services (KapaStartThread and KapaContinueThread), and the three flows.

Salesforce does not deploy credential values. In production, open the external credential's principal and enter your Kapa API key again, then assign the permission set to the users you identified earlier. Activate the flows last.

info

Kapa's Chat endpoints allow 20 requests per minute per team by default, shared with your other Kapa integrations such as the Website Widget. Each customer message uses one request. If your support team receives more messages than that at peak times, ask Kapa support to raise the rate limit before you go live.

Start with a test email address (optional)​

To try drafting on real cases before rolling it out to every customer, limit both trigger flows to one email address you control, such as your own mailbox or a shared test inbox, before you activate them. Cases from other customers get no drafts until you remove the limit.

In Kapa: Draft Reply on New Case, open the Start element and add one more entry condition:

  • Web Email Equals your test address. Web-to-Case fills this field with the address entered on your web form. The field list shows fields by label; its API name is SuppliedEmail.

Because the origin conditions use OR and the email condition must always apply, change Condition Requirements to Custom Condition Logic Is Met and combine them, for example (1 OR 2) AND 3 for two origins and the test address. With a single origin, All Conditions Are Met (AND) is enough.

Testing portal cases

Cases opened by a logged-in portal user often have no Web Email. To test the portal, add the condition Contact ID (ContactId) Equals your test contact's ID, which starts with 003 and appears in the contact's page URL. To test the web form and the portal together, accept either test condition, for example (1 OR 2) AND (3 OR 4).

In Kapa: Draft Reply on Inbound Email, add one more entry condition:

  • From Address (FromAddress) Equals your test address.

When you are happy with the drafts, go live: open each flow, remove the test condition (and set the case flow's logic back to Any Condition Is Met (OR)), click Save As New Version, and activate the new version.

FAQ​

Can I pause drafting at any time?​

Yes. Drafting is controlled by the two trigger flows, so you can pause and resume it in seconds, for example during a large import or while you fine-tune the setup:

  1. In Setup, go to Process Automation > Flows.
  2. Open Kapa: Draft Reply on New Case and click Deactivate. Do the same for Kapa: Draft Reply on Inbound Email.

Everything else stays in place: the credential, the subflow, and the thread IDs on your cases. To resume, open each flow and click Activate; follow-up emails on existing cases continue their Kapa threads as before. Cases and emails that arrive while drafting is paused do not get a draft afterwards.

Which cases get a draft?​

Every case and inbound email that matches the trigger flows' entry conditions, whoever the case is assigned to. To draft only for some cases, for example one queue or one case type, see Limit drafts to specific cases.

Can customers see the drafts?​

No. Drafts are private case comments, visible only to your team. Nothing reaches the customer until an agent writes and sends the reply.

Does a draft know about earlier messages on the case?​

Yes. The first message on a case starts a Kapa thread, and every later message continues it, so each draft takes the earlier conversation into account.

Troubleshooting​

  • No draft appears: in Setup, go to Process Automation > Paused and Failed Flow Interviews and check for a failed interview. Salesforce also emails flow errors to the user who last modified the flow, or to the address set in Process Automation > Process Automation Settings. If nothing failed, Kapa likely returned an error. Open Kapa: Draft Case Reply, click Debug, enter a case ID and a test message as the inputs, and check the callout action's responseCode in the debug output.

If the debug output shows an error responseCode, the likely causes are:

responseCodeLikely cause
400Usually a message longer than the 25,000 characters Kapa accepts in one query, for example an email with a very long quoted history.
401 or 403The API key is wrong or belongs to a different Kapa project than your project ID, the custom header is not named X-API-KEY, or Allow Formulas in HTTP Header is unchecked on the named credential.
404The project ID or integration ID constant is wrong.
429You hit Kapa's Chat rate limit. Those messages get no draft; ask Kapa support to raise the limit if it happens regularly.

Other problems:

  • "We couldn't access the credential(s)": the user the flow runs as has no access to the external credential principal. Check two things. First, the permission set's External Credential Principal Access page lists Kapa_API - Kapa; if the table is empty, follow Give users access to the credential steps 2 to 4. Second, the Created By user of the case or email has the Kapa API Access permission set; if not, add them under Manage Assignments.
  • Two drafts on an email case: your Email-to-Case routing address sets a case origin that the case flow's entry conditions include. Check the Case Origin value on a case created from email and remove it from the conditions.
  • Drafts for auto-replies: out-of-office replies are inbound emails too. Add an entry condition to the email flow that skips them by subject, since most auto-replies start with a phrase such as Automatic reply or Out of Office.
  • Drafts on bulk imports: importing many cases or emails at once drafts a reply for each of them and quickly hits the rate limit. Deactivate the trigger flows during large imports.

Summary​

In this tutorial, you:

  • Stored your Kapa API key in an external credential and a named credential, and gave the users the flows run as access to it.
  • Built a reusable subflow that starts or continues a Kapa thread for a case and posts the drafted reply as an internal case comment.
  • Added record-triggered flows that call the subflow for every new web or portal case and every inbound customer email.

Next steps​