# flux/openapi — OpenAPI 3.1 (generated)
---
openapi: 3.1.0
info:
  title: Accoil AI Workflows API
  version: '1'
paths:
  "/{account_slug}/flux/products":
    post:
      operationId: create_product
      summary: Add a product to research
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                product:
                  type: object
                  properties:
                    name:
                      type: string
                    url:
                      type: string
                      format: uri
                      description: the product's site; scheme optional
                    description:
                      type: string
                      description: optional; normally filled by research
                  required:
                  - name
                  - url
              required:
              - product
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/reviews/{review_account_id}/review_runs":
    post:
      operationId: run_customer_review
      summary: Queue a customer account review
      description: Reads the tracked account's record, ledger and the program's playbook,
        and fresh Accoil data. Selectively reads configured CRM/support context, costs
        real AI spend charged to this account, records a new review, and schedules
        the next follow-up. Refuses a second active run for the same tracked account,
        and refuses when the account's AI spending cap is reached.
      requestBody:
        description: No body — an empty request.
        required: false
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/review_program":
    post:
      operationId: create_review_program
      summary: Turn on customer reviews for this product
      description: Creates the product's review program and seeds its playbook from
        the template; running it again is a no-op. Spends nothing by itself — mapping,
        ICP evaluation and reviews are the paid runs.
      requestBody:
        description: No body — an empty request.
        required: false
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/reviews/mappings":
    post:
      operationId: track_review_account
      summary: 'Track an account: queue a paid mapping run that finds it across your
        connected systems'
      description: Needs at least one of id, account_name or domain; provider narrows
        which system the id belongs to. Costs real AI spend charged to this account;
        refused with the reason when the cap is spent, Flux is not configured, Accoil
        is not connected, or the playbook's mapping policy cannot be used. The account
        appears in the tracked accounts when the run finishes; a failed run is listed
        under recent mapping runs.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                account_mapping:
                  type: object
                  properties:
                    provider:
                      type: string
                      enum:
                      - accoil
                      - hubspot
                      - intercom
                      description: the system the id belongs to; optional
                    id:
                      type: string
                      description: the account's ID in that system
                    account_name:
                      type: string
                    domain:
                      type: string
              required:
              - account_mapping
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/reviews/{review_account_id}/icp_evaluation":
    post:
      operationId: evaluate_review_icp
      summary: Queue a paid ICP evaluation of a tracked account
      description: Judges the company against the playbook's ideal customer profile
        and updates its ICP fit and profile — except values your team set or confirmed.
        Costs real AI spend charged to this account; refused with the reason when
        the cap is spent, Flux is not configured, the identity needs review, or the
        playbook has no ideal customer profile.
      requestBody:
        description: No body — an empty request.
        required: false
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/reviews/{review_account_id}/record":
    patch:
      operationId: update_review_record
      summary: Correct a tracked account's record
      description: Each value that actually changes is saved and marked as set by
        your team; the review, mapping and ICP agents then leave it alone until the
        mark is cleared. A source mapping is corrected by its ID, which becomes your
        team's confirmed match for that system. Notes are saved but never marked —
        no agent writes them. Admins and owners only; refused on a suspended account.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                record:
                  type: object
                  properties:
                    display_name:
                      type: string
                    canonical_domain:
                      type: string
                    identity_status:
                      type: string
                      enum:
                      - confirmed
                      - partial
                      - needs_review
                      description: blank means not mapped
                    icp_fit:
                      type: string
                      enum:
                      - strong
                      - moderate
                      - weak
                      - unknown
                      description: blank means not evaluated
                    review_enabled:
                      type: string
                      enum:
                      - '0'
                      - '1'
                      description: 1 turns reviews on for this account
                    next_review_at:
                      type: string
                      format: date
                      description: the next scheduled review
                    notes:
                      type: string
                      description: your team's own notes (Markdown)
                    company_profile:
                      type: object
                      properties:
                        industry:
                          type: string
                        company_size:
                          type: string
                        employee_count:
                          type: string
                        headquarters_country:
                          type: string
                        operating_regions:
                          type: string
                        business_model:
                          type: string
                        product_category:
                          type: string
                        customer_since:
                          type: string
                    source_mappings:
                      type: object
                      additionalProperties:
                        type: string
                      description: provider => that system's ID for this account;
                        only providers already mapped
              required:
              - record
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/reviews/{review_account_id}/ledger":
    patch:
      operationId: update_review_ledger
      summary: Correct sections of a tracked account's narrative ledger
      description: Each section that changes is saved and marked as set by your team;
        the process that normally writes it then leaves it alone. Admins and owners
        only; refused on a suspended account.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ledger:
                  type: object
                  properties:
                    sections:
                      type: object
                      properties:
                        Account context:
                          type: string
                        Company profile:
                          type: string
                        Identity open loops:
                          type: string
                        Important people:
                          type: string
                        What we have learned:
                          type: string
                        ICP evaluation:
                          type: string
                        Expected use cases:
                          type: string
                        ICP gaps:
                          type: string
                        Current picture:
                          type: string
                        Current evidence:
                          type: string
                        Current hypotheses and unknowns:
                          type: string
                        Open loops:
                          type: string
              required:
              - ledger
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/reviews/{review_account_id}/confirmation":
    post:
      operationId: confirm_review_values
      summary: Mark record values as confirmed by your team, without changing them
      description: Confirmed values are left alone by the review, mapping and ICP
        agents. all=true confirms every value on the record and the mapping and ICP
        ledger sections — never a review's current sections, which are each review's
        fresh judgement.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                targets:
                  type: array
                  items:
                    type: string
                  description: field names (display_name, company_profile.industry,
                    source_mappings.hubspot) or ledger sections as ledger.<Section
                    name>
                all:
                  type: boolean
                  description: every value instead of listed targets
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
    delete:
      operationId: release_review_values
      summary: Clear your team's marks so the agents maintain those values again
      description: all=true clears every mark on the record.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                targets:
                  type: array
                  items:
                    type: string
                  description: field names (display_name, company_profile.industry,
                    source_mappings.hubspot) or ledger sections as ledger.<Section
                    name>
                all:
                  type: boolean
                  description: every value instead of listed targets
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/reviews/playbook/{name}":
    patch:
      operationId: update_playbook_document
      summary: Save a new version of one customer-review playbook document
      description: "{name} is the document's file name without .md, e.g. ideal_customer_profile
        or account-mapping. Appends a version; earlier versions are kept, and the
        review agents read the newest. Refused with 409 when base_version is not the
        current version — read the document again first. account-mapping's YAML front
        matter is validated as the mapping policy; it may choose among the permitted
        read-only tools but never add one. Admins and owners only; refused on a suspended
        account."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                playbook_document:
                  type: object
                  properties:
                    content:
                      type: string
                      description: the document's full Markdown content
                    base_version:
                      type: integer
                      description: the version you read; the save is refused (409)
                        if someone saved a newer one since
                  required:
                  - content
                  - base_version
              required:
              - playbook_document
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{id}":
    patch:
      operationId: update_product
      summary: Update a product's name, URL or description
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                product:
                  type: object
                  properties:
                    name:
                      type: string
                    url:
                      type: string
                      format: uri
                      description: the product's site; scheme optional
                    description:
                      type: string
                      description: optional; normally filled by research
              required:
              - product
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/deliverables":
    post:
      operationId: generate_deliverable
      summary: Generate (or regenerate) one deliverable for this product
      description: 'One deliverable per (product, type): regenerating reuses the slot
        and replaces the content. Costs real AI spend against the account''s AI spending
        cap; refused with a named reason when the cap is spent. A ready deliverable
        has a 24-hour regeneration cooldown; a failed one can be retried immediately.
        Throttled to 5 generations per account per minute (429 beyond that).'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                deliverable:
                  type: object
                  properties:
                    deliverable_type:
                      type: string
                      enum:
                      - product_analysis
                      - business_case
                      - tracking_plan
                      - customer_discovery
                      - engagement_playbook
                      - engagement_playbook_deep
                      - engagement_playbook_from_config
                      - whats_next
                      description: which report to generate; each type maps to one
                        AI workflow
                  required:
                  - deliverable_type
              required:
              - deliverable
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/intervention":
    post:
      operationId: run_intervention
      summary: Run the account intervention review (proof of concept)
      description: 'Assembles the demo account''s ledger, this product''s engagement
        playbook, and mocked Accoil/Intercom/HubSpot connector data into one payload,
        then runs the two-stage account-intervention process on it. Requires a ready
        engagement playbook for this product; refused otherwise. One intervention
        slot per product (across scenarios): running again replaces the previous review.
        Costs real AI spend against the account''s AI spending cap.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                scenario:
                  type: string
                  enum:
                  - acme-inc
                  - beacon-labs
                  description: which demo account to review; defaults to acme-inc
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/logo":
    post:
      operationId: fetch_logo
      summary: Discover and attach a logo for this product
      description: Queues a background fetch of the logo Brandfetch's CDN serves for
        the product URL's domain. Replaces the current logo when one is already attached;
        finding none leaves the product as it was.
      requestBody:
        description: No body — an empty request.
        required: false
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/share_links":
    post:
      operationId: create_share_link
      summary: Create a public share portal for chosen reports
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                share_link:
                  type: object
                  properties:
                    label:
                      type: string
                      description: what you call this portal; viewers never see it
                    allowed_email_domains:
                      type: array
                      items:
                        type: string
                      description: domains whose emails pass the viewer gate; EMPTY
                        ADMITS NOBODY (fail closed). The HTML form also accepts a
                        comma-separated string.
                    expires_at:
                      type: string
                      format: date-time
                      description: optional; the portal 404s after this moment
                    deliverable_ids:
                      type: array
                      items:
                        type: integer
                      description: the reports to expose — required; nothing defaults
                        onto a portal
                  required:
                  - deliverable_ids
              required:
              - share_link
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/{account_slug}/flux/products/{product_id}/share_links/{id}":
    delete:
      operationId: revoke_share_link
      summary: Revoke a share link
      description: 'Revokes rather than deletes: the portal stops answering immediately,
        but the link and its viewer history are kept.'
      requestBody:
        description: No body — an empty request.
        required: false
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
  "/share/{token}/viewers":
    post:
      operationId: pass_email_gate
      summary: Pass a share portal's email gate (public — no account token needed)
      description: Admits you when your email's domain is on the link's allow list,
        and sets a viewer cookie. An empty allow list admits nobody — ask the sender
        to add your domain.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                viewer:
                  type: object
                  properties:
                    email:
                      type: string
                      format: email
                      description: the work email the link was sent to
                  required:
                  - email
              required:
              - viewer
      responses:
        '200':
          description: OK
        '403':
          description: Read-only token, or not permitted
