Skip to content

Categorize inbound form submissions with Data Agent: Custom prompt, then route by category

One of 565 written HubSpot workflow specs, by a collective of independent HubSpot consultants.

Free
Professional

Seat pricing: Professional edition. To build it, a GTM Seat or an Ops Seat (an Ops Seat cannot create marketing emails or sequences). Per-hub plans: Sales Hub Professional.

Per-hub plans: also Marketing Hub ProfessionalUpdated for HubSpot seat pricing
OutcomeEvery contact form message gets a category within minutes of submission, and the record lands with the right team (sales, support, partnerships or spam) without a human reading the free-text field first.
Workflow mapai-agents-001
Form submitted with Message and review status reset leads to Data Agent Custom prompt returns category. Data Agent Custom prompt returns category leads to Output known. Output known leads to No: Mark pending review and create manual task; Yes: Write AI category and stamp output time. Write AI category and stamp output time leads to Category. Category leads to sales: Rotate to sales pool and create call task; support or partnership or spam or unclear: Set owner or flag for review. No Yes sales support or partnership or spam or unclear Form submitted with Message and review status reset Data Agent Custom prompt returns category Output known Mark pending review and create manual task Write AI category and stamp output time Category Rotate to sales pool and create call task Set owner or flag for review
Form submitted with Message and review status reset leads to Data Agent Custom prompt returns category. Data Agent Custom prompt returns category leads to Output known. Output known leads to No: Mark pending review and create manual task; Yes: Write AI category and stamp output time. Write AI category and stamp output time leads to Category. Category leads to sales: Rotate to sales pool and create call task; support or partnership or spam or unclear: Set owner or flag for review. No Yes sales support or partnership or spam or unclear Form submitted with Message and review status reset Data Agent Custom prompt returns category Output known Mark pending review and create manual task Write AI category and stamp output time Category Rotate to sales pool and create call task Set owner or flag for review

When to use it, when not to

Use it

  • Use it when the main contact form has one free-text field and the inbox behind it mixes sales requests, support questions, vendor pitches and spam, and someone sorts that by hand every morning.
  • Use it when the categories are few and stable (4 to 6). The prompt and the enumeration both get worse as the list grows.

Skip it

  • Do not use it when the form already has a required "Reason for contact" dropdown. Branch on that dropdown instead, it costs nothing and never misreads.
  • Do not use it for lead assignment inside the sales team by territory or size. That is lead-routing-010 territory; this spec only decides which team sees the record first.

Prerequisites

Needs Sales Hub Professional and Marketing Hub Professional.

On per-hub plans, one of its steps belongs to another subscription: add to static list needs Marketing Hub Professional. Both are required to build it as written. On seat pricing the edition covers both.

Properties to create on the contact object:

  • Label AI category, internal name ai_category, object contact, field type dropdown select, options sales, support, partnership, spam, unclear. Why: the Data Agent output is written here, the branches read it, and reports count it.
  • Label AI output at, internal name ai_output_at, object contact, field type date and time picker. Why: stamps when the AI last ran so you can see stale or missing outputs.
  • Label AI review status, internal name ai_review_status, object contact, field type dropdown select, options not needed, pending review, reviewed. Why: the fallback branch marks records a human must look at.

Other prerequisites:

  • Sales Hub Professional or Enterprise. Every AI action in workflows needs a Professional or Enterprise subscription of Marketing Hub, Sales Hub, Service Hub, Data Hub, Smart CRM or Revenue Hub.
  • HubSpot Credits in the account. Each run of Data Agent: Custom prompt consumes credits. When the balance hits zero the action fails and its output is null, which is why step 3 branches on an empty output. Per-action credit cost is not published: *(check in your portal: how many credits one Data Agent: Custom prompt run consumes in your account, read from the credits usage page after the test plan)*.
  • Account settings Give users access to generative AI tools switched on, plus the CRM data setting for AI.
  • A form with a free-text field, for example the default Message property, and the form connected to this workflow through the enrollment trigger.
  • A sales rep pool, a support team queue and a partnerships owner to receive the routed records.

Enrollment

Trigger typeevent-based.
CriteriaForm submission on form Contact us (any page), filtered to Message is known.
Re-enrollmenton, re-enroll on every new form submission. A contact who writes twice gets categorized twice, and the second category overwrites the first.
Suppression / exclusionsLifecycle stage is none of Customer. Customers writing in go straight to support through tickets-sla specs, not through this categorization.

Steps

  1. Set property value: AI review status = not needed. Resets the flag before the AI runs, so a second submission does not inherit a stale review state.
  2. Data Agent: Custom prompt. Output type: enumeration with the exact five options of AI category. Prompt (well under the 3,000 character limit): "You classify a website contact form message. The sender works at {{contact.company}} with the job title {{contact.jobtitle}}. The message is: {{contact.message}}. Return exactly one of: sales (wants to buy, pricing, demo), support (existing product problem), partnership (resell, integrate, co-market), spam (unrelated, promotional, nonsense), unclear (cannot tell)." The model has no internet access, so every piece of context must be a token in the prompt like this.
  3. If/then branch: Data Agent output is known.
    • No (credits exhausted, action failed, model returned nothing): Set property value AI review status = pending review. Create task, type To-do, assigned to the inbound owner, due in 1 business day, subject "Categorize by hand: {{contact.email}}", body "AI categorization returned no value. Read the message and set AI category manually." End of this branch.
    • Yes: continue to step 4.
  4. Set property value: AI category = the Data Agent output (Edit record, pick the action output as the value source). Set property value: AI output at = current date and time.
  5. If/then branch on AI category:
    • sales: Rotate record to owner, pool = inbound sales reps. Create task, type Call, assigned to record owner, due in 1 business day, subject "New inbound sales request: {{contact.firstname}} {{contact.lastname}}".
    • support: Set property value Contact owner = support queue owner. Send internal email notification to the support inbox, subject "Website message flagged as support: {{contact.email}}".
    • partnership: Set property value Contact owner = partnerships manager. Send internal email notification to that manager.
    • spam: Set property value Lifecycle stage = Other. No notification. Done.
    • unclear: Set property value AI review status = pending review. Create task, type To-do, assigned to the inbound owner, due in 1 business day, subject "Unclear website message: {{contact.email}}".

Known pitfalls

  • The enumeration output and the dropdown property must carry the same option values, spelled the same way. One typo in partnership and the Edit record step writes nothing, which looks exactly like an AI failure.
  • The output must be defined before the action saves. If the editor refuses to save the Data Agent step, the output configuration is incomplete, not the prompt.
  • Re-enrollment on every submission means every submission spends credits. A contact who submits the same form five times costs five runs. Add a suppression on Number of form submissions greater than 10 if bots hit the form.
  • A null output and a genuine unclear are two different things. The first means the AI did not run, the second means it ran and could not decide. Keep both paths, they tell you different things about the setup.
  • Spam classification by the model is a guess. Review the spam bucket weekly for the first month before trusting it to hide records from the team.
  • Rotate record to owner only rotates among users who are active and in the chosen team. A rep on leave still receives records unless removed from the team.

Test plan

  1. In the test portal, submit the form with a message that reads like a pricing request. Confirm the contact enrolls (Automation > Workflows > this workflow > History).
  2. Open the contact record: AI category = sales, AI output at stamped, Contact owner set to a pool member, a Call task created.
  3. Submit again from the same contact with a support-type message. Confirm re-enrollment and that AI category now reads support.
  4. Submit with nonsense text and confirm AI category = spam and Lifecycle stage = Other.
  5. Force the failure path: temporarily switch the generative AI setting off, submit once more, and confirm the task "Categorize by hand" appears with AI review status = pending review. Switch the setting back on.

The UAT script of this spec holds 9 cases: a negative case, one case per branch, the expected result of each and a sign-off sheet. It comes as Markdown and as a CSV for your spreadsheet.

Variants

  • Ticket object: run the same prompt on new tickets from the support form and set Category instead of routing contacts; see ai-agents-012 for the sentiment and urgency version.
  • Marketing Hub Professional portal: replace the sales rotation with Add to static list per category and let the marketing team work the lists.
  • Wait until: instead of acting on the first output, add a Wait until step on AI review status is reviewed with a 2 business day expiry for the unclear branch, then route on the human-corrected AI category.

Build spec

Build specYAML, swipe
trigger:
  type: event-based
  object: contact
  event: form_submission
  form: "Contact us"
  criteria:
    - message: is_known
    - lifecyclestage: is_none_of ["customer"]
  reenrollment: true
  reenrollment_event: form_submission
actions:
  - type: set_property_value
    property: ai_review_status
    value: not_needed
  - type: data_agent_custom_prompt
    installable: false
    manual_step: "Add the AI action Data Agent: Custom prompt. Output type enumeration with options sales, support, partnership, spam, unclear. Paste the prompt from step 2 with the contact tokens."
    output_type: enumeration
    output_options: [sales, support, partnership, spam, unclear]
  - type: if_then_branch
    condition: data_agent_output_is_known
    if_false:
      - type: set_property_value
        property: ai_review_status
        value: pending_review
      - type: create_task
        task_type: todo
        title: "Categorize by hand: {{contact.email}}"
        due: +1_business_day
        assigned_to: inbound_owner
    if_true:
      - type: set_property_value
        property: ai_category
        value: "{{action_output.category}}"
      - type: set_property_value
        property: ai_output_at
        value: current_datetime
      - type: if_then_branch
        condition: ai_category
        branches:
          sales:
            - type: rotate_record_to_owner
              pool: "Inbound sales reps"
            - type: create_task
              task_type: call
              title: "New inbound sales request: {{contact.firstname}} {{contact.lastname}}"
              due: +1_business_day
              assigned_to: record_owner
          support:
            - type: set_property_value
              property: hubspot_owner_id
              value: support_queue_owner
            - type: send_internal_email_notification
              to: support_inbox
              subject: "Website message flagged as support: {{contact.email}}"
          partnership:
            - type: set_property_value
              property: hubspot_owner_id
              value: partnerships_manager
            - type: send_internal_email_notification
              to: partnerships_manager
              subject: "Partnership request: {{contact.email}}"
          spam:
            - type: set_property_value
              property: lifecyclestage
              value: other
          unclear:
            - type: set_property_value
              property: ai_review_status
              value: pending_review
            - type: create_task
              task_type: todo
              title: "Unclear website message: {{contact.email}}"
              due: +1_business_day
              assigned_to: inbound_owner

Files and install

FileWhat it holds
PDF and MarkdownThe spec as you read it here, with the YAML build spec at the end.
Properties JSONCreates the fields in one API call.
Workflow JSONDocuments the build: the workflow in Automation API v4 format, switched off.
UAT scriptThe test cases, the expected results and a sign-off sheet, as Markdown and CSV.

Take the PDF and build it by hand. One-click install comes with a category pack or the full library.

Get the 12 free specs as a pack

Nothing deleted, enabled or enrolled.

ai-agents-001Spec version 2026-10

Read 12 complete specs before you pay.

One per category, same format as the paid ones. Email only, no card.

We email the link, then a short note when specs change. Nothing else.

All 12 free specs by email, no card.