# Origamy playbook spec v1. Reference: /playbooks/spec-format/
spec_version: 1
id: insurtech.claims-updates
title: Claims status updates
sector: insurtech
source:
  kind: synthesized
  notes: >-
    No insurer has built this with us yet. Written from the per-decision message pattern of the
    loan application follow-up (a trigger filter on one property picks the message), the
    documents-still-missing reminder, and a daily check for work that has gone quiet. It works
    from a staff "Claim update" form with no code, or from claim events sent by your app. No
    message carries an amount, a policy number or a claim reference.
derived_from: lending.loan-application-follow-up
vocabulary:
  person: claimant
  people: claimants
  group: claims team
summary: >-
  Keeps every claimant informed. A new claim gets an acknowledgement that says what happens
  next, and each status change (documents needed, under review, approved, paid or declined)
  sends the right message. When documents are needed, the claimant gets a secure upload link and
  a reminder three days later if the status hasn't moved. A claim that sits under review for a
  week gives a claims officer a task.
when_to_use:
  - You are an insurer or an MGA and claimants keep calling to ask "where is my claim?"
  - Your claims officers already know the status of each claim, but nobody tells the customer.
  - You want claims that stall to be noticed, not forgotten.

requires:
  data_in:
    - how: public_form
      what: "The Report a claim form and the Upload documents form this playbook creates. Put the claim link on your website and in your WhatsApp replies."
    - how: staff_form
      what: "The Claim update form your claims officers fill in each time a claim changes status, matched by phone. This is the no-code way."
    - how: app_events
      what: "Or, with the app option, your claims system sends a claim-submitted event and a status-changed event with a status property."
  channels:
    - channel: sms
      for: Every message to claimants
      needs: An SMS provider, or Origamy managed SMS after business verification (KYC).
  events:
    - onboarding.submitted
    - "{{ params.submitted_event }}"
    - "{{ params.status_event }}"
  traits:
    - claim_status
    - claim_updated_at
    - claim_review_call
    - claim_declined_call
    - claim_documents_review

parameters:
  - key: org_name
    ask: true
    question: What should messages call your company?
    label: Company name
    type: string
    example: Northwind Insurance
  - key: claims_source
    ask: true
    question: "How do claim updates reach Origamy? Choose form (no code: a claim form and a staff update form) or app (your claims system sends events)."
    label: Data source
    type: enum
    options: [form, app]
    default: form
  - key: claims_team
    ask: true
    question: Which team handles claims and the calls this playbook creates? (claims officers, one person is fine)
    label: Claims officers
    type: team_name
    default: Claims officers
  - key: claims_phone
    ask: true
    question: Which number should claimants call about their claim?
    label: Claims phone
    type: string
    default: "{{ workspace.phone }}"
  - key: stuck_days
    ask: true
    question: After how many days under review with no update should a claims officer be asked to look?
    label: Days before a claim counts as stuck
    type: days
    default: 7
  - key: submitted_event
    label: Event your system sends when a claim is submitted
    type: event_name
    default: claim.submitted
  - key: status_event
    label: Event your system sends when a claim's status changes (with a status property)
    type: event_name
    default: claim.status_changed
  - key: claim_types
    label: Claim types on the claim form
    type: list
    default: [Motor, Home, Travel, Business]
  - key: docs_remind_days
    label: Days to wait for documents before the reminder
    type: days
    default: 3
  - key: stuck_stop_days
    label: Days after which a stuck claim is no longer raised
    type: days
    default: 90
  - key: call_due_hours
    label: Hours the claims team has to make a call
    type: hours
    default: 24
  - key: send_time
    label: Daily run time for the stuck-claim check
    type: time
    default: "09:00"
  - key: default_country
    label: Default phone country on the forms
    type: country_code
    default: "{{ workspace.country }}"
  - key: timezone
    label: Time zone for the daily run
    type: timezone
    default: "{{ workspace.timezone }}"
  - key: greeting_fallback
    label: Greeting when a first name is missing
    type: string
    default: there

timings:
  - A new claim gets an acknowledgement SMS straight away.
  - Each status change sends its message straight away, and saves the status and the time on the claimant.
  - "Documents needed: the upload link goes at once. If the status is still documents needed {{ params.docs_remind_days }} days later, a reminder goes."
  - Documents uploaded through the form get an SMS straight away and a review task for {{ params.claims_team }}.
  - "Every day at {{ params.send_time }} ({{ params.timezone }}), claims under review with no update for {{ params.stuck_days }} days (and less than {{ params.stuck_stop_days }} days) create a task for {{ params.claims_team }}, due in {{ params.call_due_hours }} hours. Each claim is raised at most once a week."

customer_must:
  - "With the form option: publish the Report a claim, Claim update and Upload documents forms. Officers fill in Claim update, with the claimant's phone number, every time a status changes: documents needed, under review, approved, paid or declined. With the app option: send {{ params.submitted_event }} and {{ params.status_event }} with a status property that is one of documents_needed, under_review, approved, paid or declined."
  - "Never leave the status blank, and use only the five statuses. The stuck-claim check and the documents reminder read the status, so a wrong value means a missed message."
  - "Never put an amount, a policy number, a claim reference or the reason for a decline in a message. Messages say only what changed and who to call. Decline reasons are given by a claims officer, in writing or on the phone, under your regulator's rules."
  - "Tell claimants, on the claim form and in your branch, that documents go only through the upload form and that you will never ask for a PIN, password or code. No message here asks for one."
  - Add people to the {{ params.claims_team }} team. A task assigned to an empty team reaches nobody. Limit who can open submitted forms, because claim forms and uploads hold personal documents.
  - Connect an SMS provider or finish business verification, switch the follow-ups on, and test each status with your own phone and a fake claim.

objects:
  - ref: team_claims
    kind: team
    about: Handles document reviews, declined-claim calls and stuck claims.
    body: { name: "{{ params.claims_team }}" }

  - ref: form_claim
    kind: form
    about: The claim form (the no-code way in). Claim details stay on the form; messages never repeat them.
    when: { param: claims_source, equals: form }
    body:
      name: Report a claim
      slug: report-a-claim
      description: Tell us what happened and we'll look after your claim. We will never ask for your PIN, password or any code.
      draft_state:
        version: 1
        meta: { layout: classic, submit_label: Submit claim, success_message: "Thank you! We've received your claim and will update you by SMS." }
        pages:
          - id: p1
            title: Your details
            description: Tell us who you are and how to reach you.
            fields:
              - { id: f_first, key: first_name, type: short_text, label: First name, required: true, maps_to: { mode: custom, key: first_name, trait: true } }
              - { id: f_last, key: last_name, type: short_text, label: Surname, required: true, maps_to: { mode: custom, key: last_name, trait: true } }
              - { id: f_phone, key: phone, type: phone, label: Phone number, required: true, maps_to: { mode: mapped, slot: profile.phone }, config: { country_picker: true, default_country: "{{ params.default_country }}", verify: "off" } }
              - { id: f_email, key: email, type: email, label: Email address, required: false, maps_to: { mode: mapped, slot: profile.email } }
          - id: p2
            title: Your claim
            description: Tell us what happened.
            fields:
              - id: f_type
                key: claim_type
                type: single_select
                label: What is the claim for?
                required: true
                maps_to: { mode: custom, key: claim_type }
                options:
                  $each: params.claim_types
                  $value: { value: "{{ item }}", label: "{{ item }}" }
              - { id: f_what, key: what_happened, type: long_text, label: What happened?, required: true, maps_to: { mode: custom, key: what_happened } }
              - { id: f_consent, key: consent_to_review, type: boolean, label: I agree that my details may be used to handle this claim, required: true, maps_to: { mode: custom, key: consent_to_review } }
      verification_settings: { required: false }
  - ref: form_update
    kind: form
    about: Staff-only form where a claims officer records each status change. Matched to the claimant by phone.
    when: { param: claims_source, equals: form }
    body:
      name: Claim update
      slug: claim-update
      description: Claims officers only. One entry each time a claim changes status.
      draft_state:
        version: 1
        meta: { layout: classic, submit_label: Save update, success_message: Saved. The claimant will be told by SMS. }
        pages:
          - id: p1
            title: Claim update
            description: Use the phone number from the claim. Do not enter an amount, a policy number or a decline reason.
            fields:
              - { id: f_phone, key: phone, type: phone, label: Claimant's phone number, required: true, maps_to: { mode: mapped, slot: profile.phone }, config: { country_picker: true, default_country: "{{ params.default_country }}", verify: "off" } }
              - id: f_status
                key: status
                type: single_select
                label: New status
                required: true
                maps_to: { mode: custom, key: claim_status, trait: true }
                options:
                  - { value: documents_needed, label: Documents needed }
                  - { value: under_review, label: Under review }
                  - { value: approved, label: Approved }
                  - { value: paid, label: Paid }
                  - { value: declined, label: Declined }
              - { id: f_note, key: internal_note, type: long_text, label: Internal note (never sent to the claimant), required: false, maps_to: { mode: custom, key: internal_note } }
      verification_settings: { required: false }
  - ref: form_docs
    kind: form
    about: A short form for claimants to upload the documents asked for. Documents go only through this form.
    body:
      name: Upload documents
      slug: upload-claim-documents
      description: Send us the documents we asked for. We will never ask for your PIN, password or any code.
      draft_state:
        version: 1
        meta: { layout: classic, submit_label: Send documents, success_message: "Thank you! Our team will review your documents." }
        pages:
          - id: p1
            title: Upload your documents
            description: Use the same phone number you gave us for your claim.
            fields:
              - { id: f_phone, key: phone, type: phone, label: Phone number on your claim, required: true, maps_to: { mode: mapped, slot: profile.phone }, config: { country_picker: true, default_country: "{{ params.default_country }}", verify: "off" } }
              - { id: f_doc1, key: document_one, type: file, label: Document, required: true, maps_to: { mode: custom, key: document_one }, validation: { mime_types: [image/jpeg, image/png, application/pdf], max_size_mb: 10 } }
              - { id: f_doc2, key: document_two, type: file, label: Another document (if asked), required: false, maps_to: { mode: custom, key: document_two }, validation: { mime_types: [image/jpeg, image/png, application/pdf], max_size_mb: 10 } }
              - { id: f_doc3, key: document_three, type: file, label: Another document (if asked), required: false, maps_to: { mode: custom, key: document_three }, validation: { mime_types: [image/jpeg, image/png, application/pdf], max_size_mb: 10 } }
      verification_settings: { required: false }

  - ref: seg_stuck
    kind: segment
    about: Under review with no status change for a while.
    body:
      name: Claim under review, no update
      description: "claim_status is under_review and claim_updated_at is more than {{ params.stuck_days }} days ago but within the last {{ params.stuck_stop_days }} days."
      segment_type: dynamic
      status: active
      definition:
        operator: and
        conditions:
          - { type: trait, trait_key: claim_status, cond_operator: eq, value: under_review }
          - { type: trait, trait_key: claim_updated_at, cond_operator: older_than, value: "{{ params.stuck_days }}d" }
          - { type: trait, trait_key: claim_updated_at, cond_operator: within_last, value: "{{ params.stuck_stop_days }}d" }

  - ref: tmpl_ack
    kind: template
    about: "Acknowledgement with what happens next."
    body:
      name: Claim received (SMS)
      channel: sms
      category: Claims
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "{{ params.org_name }}: thank you, {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}. We have received your claim. A claims officer will review it and we will text you at every step, including if we need documents. Questions? Call {{ params.claims_phone }}. We will never ask for your PIN, password or any code. Reply STOP to opt out."
  - ref: tmpl_docs
    kind: template
    about: "Secure upload link when documents are needed."
    body:
      name: Documents needed (SMS)
      channel: sms
      category: Claims
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "{{ params.org_name }}: hello {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}, we need a few documents to continue your claim. Please upload them here: {{ ref.form_docs.url }} Not sure what is needed? Call {{ params.claims_phone }}. We will never ask for your PIN, password or any code. Reply STOP to opt out."
  - ref: tmpl_docs_reminder
    kind: template
    about: "Reminder when documents are still outstanding."
    body:
      name: Documents reminder (SMS)
      channel: sms
      category: Claims
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "{{ params.org_name }}: hello {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}, a friendly reminder that we are still waiting for the documents for your claim. Upload them here: {{ ref.form_docs.url }} Need help? Call {{ params.claims_phone }}. We will never ask for your PIN, password or any code. Reply STOP to opt out."
  - ref: tmpl_review
    kind: template
    about: "Status message: the claim is being reviewed."
    body:
      name: Claim under review (SMS)
      channel: sms
      category: Claims
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "{{ params.org_name }}: hello {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}, your claim is now under review. We will text you as soon as there is an update. Questions? Call {{ params.claims_phone }}. Reply STOP to opt out."
  - ref: tmpl_approved
    kind: template
    about: "Status message: approved. No amounts."
    body:
      name: Claim approved (SMS)
      channel: sms
      category: Claims
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "{{ params.org_name }}: good news, {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}. Your claim has been approved. We will text you when payment is on its way. Questions? Call {{ params.claims_phone }}. Reply STOP to opt out."
  - ref: tmpl_paid
    kind: template
    about: "Status message: paid. No amounts."
    body:
      name: Claim paid (SMS)
      channel: sms
      category: Claims
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "{{ params.org_name }}: hello {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}, your claim payment has been sent. It can take a little time to show in your account. If you do not see it, call {{ params.claims_phone }}. Reply STOP to opt out."
  - ref: tmpl_declined
    kind: template
    about: "Status message: declined. Respectful, no reasons, offers a call."
    body:
      name: Claim declined (SMS)
      channel: sms
      category: Claims
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "{{ params.org_name }}: hello {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}. We are sorry, we were not able to approve your claim. A claims officer will call you to explain and talk through your options, or you can call {{ params.claims_phone }}. Reply STOP to opt out."
  - ref: tmpl_docs_received
    kind: template
    about: "Acknowledgement when documents are uploaded."
    body:
      name: Documents received (SMS)
      channel: sms
      category: Claims
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "{{ params.org_name }}: thank you, {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}. We have received your documents and our team will review them. Reply STOP to opt out."

  - ref: wf_submitted_form
    kind: workflow
    about: "A new claim gets an acknowledgement that says what happens next."
    when: { param: claims_source, equals: form }
    body:
      name: "Claim 1: submitted"
      description: A new claim is acknowledged and its status saved.
      enabled: false
      trigger_type: event
      trigger_config: { event_name: onboarding.submitted, form_id: "{{ ref.form_claim.id }}" }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: submitted, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_ack.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_submitted_app
    kind: workflow
    about: "A new claim gets an acknowledgement that says what happens next."
    when: { param: claims_source, equals: app }
    body:
      name: "Claim 1: submitted"
      description: A new claim is acknowledged and its status saved.
      enabled: false
      trigger_type: event
      trigger_config: { event_name: "{{ params.submitted_event }}" }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: submitted, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_ack.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_docs_needed_form
    kind: workflow
    about: "Documents needed: the upload link, then a reminder if the status is unchanged."
    when: { param: claims_source, equals: form }
    body:
      name: "Claim 2: documents needed"
      description: The claimant gets the upload link, and a reminder if the status has not moved.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: onboarding.submitted
        form_id: "{{ ref.form_update.id }}"
        property_filters: [{ property: status, cond_operator: eq, value: documents_needed }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: documents_needed, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_docs.id }}" } } } }
        - { id: s3, type: delay, config: { duration: "{{ params.docs_remind_days }}d" } }
        - { id: s4, type: filter, config: { condition: { type: trait, trait_key: claim_status, cond_operator: eq, value: documents_needed } } }
        - { id: s5, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_docs_reminder.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_docs_needed_app
    kind: workflow
    about: "Documents needed: the upload link, then a reminder if the status is unchanged."
    when: { param: claims_source, equals: app }
    body:
      name: "Claim 2: documents needed"
      description: The claimant gets the upload link, and a reminder if the status has not moved.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: "{{ params.status_event }}"
        property_filters: [{ property: status, cond_operator: eq, value: documents_needed }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: documents_needed, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_docs.id }}" } } } }
        - { id: s3, type: delay, config: { duration: "{{ params.docs_remind_days }}d" } }
        - { id: s4, type: filter, config: { condition: { type: trait, trait_key: claim_status, cond_operator: eq, value: documents_needed } } }
        - { id: s5, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_docs_reminder.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_under_review_form
    kind: workflow
    about: "Under review: a short status message."
    when: { param: claims_source, equals: form }
    body:
      name: "Claim 3: under review"
      description: The status is saved and the claimant is told the claim is being reviewed.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: onboarding.submitted
        form_id: "{{ ref.form_update.id }}"
        property_filters: [{ property: status, cond_operator: eq, value: under_review }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: under_review, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_review.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_under_review_app
    kind: workflow
    about: "Under review: a short status message."
    when: { param: claims_source, equals: app }
    body:
      name: "Claim 3: under review"
      description: The status is saved and the claimant is told the claim is being reviewed.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: "{{ params.status_event }}"
        property_filters: [{ property: status, cond_operator: eq, value: under_review }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: under_review, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_review.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_approved_form
    kind: workflow
    about: "Approved: a status message with no amount."
    when: { param: claims_source, equals: form }
    body:
      name: "Claim 4: approved"
      description: The status is saved and the claimant is told the claim is approved.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: onboarding.submitted
        form_id: "{{ ref.form_update.id }}"
        property_filters: [{ property: status, cond_operator: eq, value: approved }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: approved, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_approved.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_approved_app
    kind: workflow
    about: "Approved: a status message with no amount."
    when: { param: claims_source, equals: app }
    body:
      name: "Claim 4: approved"
      description: The status is saved and the claimant is told the claim is approved.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: "{{ params.status_event }}"
        property_filters: [{ property: status, cond_operator: eq, value: approved }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: approved, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_approved.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_paid_form
    kind: workflow
    about: "Paid: a status message with no amount."
    when: { param: claims_source, equals: form }
    body:
      name: "Claim 5: paid"
      description: The status is saved and the claimant is told the payment has been sent.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: onboarding.submitted
        form_id: "{{ ref.form_update.id }}"
        property_filters: [{ property: status, cond_operator: eq, value: paid }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: paid, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_paid.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_paid_app
    kind: workflow
    about: "Paid: a status message with no amount."
    when: { param: claims_source, equals: app }
    body:
      name: "Claim 5: paid"
      description: The status is saved and the claimant is told the payment has been sent.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: "{{ params.status_event }}"
        property_filters: [{ property: status, cond_operator: eq, value: paid }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: paid, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_paid.id }}" } } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_declined_form
    kind: workflow
    about: "Declined: a respectful message with no reason, and a call task."
    when: { param: claims_source, equals: form }
    body:
      name: "Claim 6: declined"
      description: The status is saved, the claimant gets a respectful message, and a claims officer is asked to call.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: onboarding.submitted
        form_id: "{{ ref.form_update.id }}"
        property_filters: [{ property: status, cond_operator: eq, value: declined }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: declined, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_declined.id }}" } } } }
        - id: s3
          type: human_task
          config:
            human_task:
              title: "Declined claim: offer a call to {{ traits.first_name | default: \"claimant\" }}"
              instructions: |-
                {{ traits.first_name | default: "This claimant" }} ({{ traits.phone }}) was told by SMS that their claim could not be approved.

                Call kindly, explain the decision in your own words under your regulator's rules, and talk through their options, including how to ask for a review. Do not discuss amounts in a message afterwards. Choose an outcome and add a short note about the call.
              assignee_refs: [{ type: team, id: "{{ ref.team_claims.id }}" }]
              strategy: round_robin
              completion_policy: first_response_wins
              outcome_options:
                - { id: explained, label: Explained and understood, intent: positive }
                - { id: wants_review, label: Wants the decision reviewed, intent: neutral }
                - { id: not_reached, label: Could not reach, intent: negative }
              due_hours: 48
              wait: true
              wait_timeout_hours: 168
              notify: immediate
        - { id: s4, type: action, config: { action_type: set_trait, traits: { claim_declined_call: "{{ properties.task_outcome | default: \"unknown\" }}" } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_declined_app
    kind: workflow
    about: "Declined: a respectful message with no reason, and a call task."
    when: { param: claims_source, equals: app }
    body:
      name: "Claim 6: declined"
      description: The status is saved, the claimant gets a respectful message, and a claims officer is asked to call.
      enabled: false
      trigger_type: event
      trigger_config:
        event_name: "{{ params.status_event }}"
        property_filters: [{ property: status, cond_operator: eq, value: declined }]
        properties: { $origamy_property_filters: true }
      steps:
        - { id: s1, type: action, config: { action_type: set_trait, traits: { claim_status: declined, claim_updated_at: "{{ now }}" } } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_declined.id }}" } } } }
        - id: s3
          type: human_task
          config:
            human_task:
              title: "Declined claim: offer a call to {{ traits.first_name | default: \"claimant\" }}"
              instructions: |-
                {{ traits.first_name | default: "This claimant" }} ({{ traits.phone }}) was told by SMS that their claim could not be approved.

                Call kindly, explain the decision in your own words under your regulator's rules, and talk through their options, including how to ask for a review. Do not discuss amounts in a message afterwards. Choose an outcome and add a short note about the call.
              assignee_refs: [{ type: team, id: "{{ ref.team_claims.id }}" }]
              strategy: round_robin
              completion_policy: first_response_wins
              outcome_options:
                - { id: explained, label: Explained and understood, intent: positive }
                - { id: wants_review, label: Wants the decision reviewed, intent: neutral }
                - { id: not_reached, label: Could not reach, intent: negative }
              due_hours: 48
              wait: true
              wait_timeout_hours: 168
              notify: immediate
        - { id: s4, type: action, config: { action_type: set_trait, traits: { claim_declined_call: "{{ properties.task_outcome | default: \"unknown\" }}" } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_docs_received
    kind: workflow
    about: Uploaded documents get an acknowledgement and a review task for the claims team.
    body:
      name: "Claim 7: documents received"
      description: SMS acknowledgement and a review task when the Upload documents form is submitted.
      enabled: false
      trigger_type: event
      trigger_config: { event_name: onboarding.submitted, form_id: "{{ ref.form_docs.id }}" }
      steps:
        - { id: s1, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_docs_received.id }}" } } } }
        - id: s2
          type: human_task
          config:
            human_task:
              title: "Review claim documents: {{ traits.first_name }} {{ traits.last_name }}"
              instructions: |-
                {{ traits.first_name }} {{ traits.last_name }} ({{ traits.phone }}) uploaded documents for their claim.

                Check them against what was asked. If everything is there, record Under review on the Claim update form (or in your claims system). If something is still missing, record Documents needed again. Choose an outcome and add a short note.
              assignee_refs: [{ type: team, id: "{{ ref.team_claims.id }}" }]
              strategy: round_robin
              completion_policy: first_response_wins
              outcome_options:
                - { id: complete, label: Everything is there, intent: positive }
                - { id: still_missing, label: Something is still missing, intent: neutral }
              due_hours: "{{ params.call_due_hours }}"
              wait: true
              wait_timeout_hours: 168
              notify: immediate
        - { id: s3, type: action, config: { action_type: set_trait, traits: { claim_documents_review: "{{ properties.task_outcome | default: \"unknown\" }}" } } }
      re_entry_policy: every_time
      re_entry_cooldown_hours: 0
      goal: {}
      exit_conditions: []
  - ref: wf_stuck
    kind: workflow
    about: 'Daily run over "claim under review, no update": a task for a claims officer, at most once a week.'
    body:
      name: "Claim 8: stuck claim"
      description: Every day, claims under review with no update for a while give the claims team a task.
      enabled: false
      trigger_type: schedule
      trigger_config: { segment_id: "{{ ref.seg_stuck.id }}", rrule: FREQ=DAILY, starts_at: "{{ workspace.tomorrow }}T{{ params.send_time }}", timezone: "{{ params.timezone }}" }
      steps:
        - id: s1
          type: human_task
          config:
            human_task:
              title: "Claim with no update: {{ traits.first_name | default: \"claimant\" }}"
              instructions: |-
                {{ traits.first_name | default: "This claimant" }} ({{ traits.phone }}) has had a claim under review for more than a week with no status change.

                Check the claim in your system, move it forward or call the claimant to say what is happening. Record the new status on the Claim update form (or in your claims system). Choose an outcome and add a short note.
              assignee_refs: [{ type: team, id: "{{ ref.team_claims.id }}" }]
              strategy: round_robin
              completion_policy: first_response_wins
              outcome_options:
                - { id: moved_on, label: Claim moved forward, intent: positive }
                - { id: waiting, label: Still waiting on a third party, intent: neutral }
                - { id: not_reached, label: Could not reach the claimant, intent: negative }
              due_hours: "{{ params.call_due_hours }}"
              wait: true
              wait_timeout_hours: 168
              notify: immediate
        - { id: s2, type: action, config: { action_type: set_trait, traits: { claim_review_call: "{{ properties.task_outcome | default: \"unknown\" }}" } } }
      re_entry_policy: cooldown
      re_entry_cooldown_hours: 168
      goal: {}
      exit_conditions: []

eval:
  name: 104_insurtech_claims_updates
  mode: task
  vertical: ""
  prompt: >-
    We're an insurer. Our claims officers will record each claim's status on a form: documents
    needed, under review, approved, paid or declined. Text the claimant the right message for each
    status. For documents needed, include a link to upload documents and send a reminder three
    days later if the status hasn't changed. If a claim sits under review for 7 days with no
    update, give our claims team a task. Acknowledge every new claim with what happens next.
    Never put an amount or a policy number in a message.
  expect_artifacts: [form, segment, workflow, message_template]
  forbid_terms: [amount, policy number]
