Live Direct Marketing Briefs API

The Briefs API from Live Direct Marketing — 23 operation(s) for briefs.

Operations 27

Each operation below carries the questions people ask an LLM about it and the instructions they give an agent to run it. Generated by API Evangelist overlay

GET /api/briefs/schemas Get the available brief JSON schemas · Get available brief JSON schemas #
Ask an LLM
“What JSON schemas can a brief's content follow?”
“Which brief schema versions are available in my workspace?”
Tell an agent
Show me the available brief JSON schemas.
Fetch the brief schemas for tenant {tenant}.
GET /api/briefs/intake Get the intake email address for a brief · Existing Brief intake address by briefId/briefUrl; omit both only before a… #
Ask an LLM
“What email address do I forward material to so it lands on a specific brief?”
“Is there a workspace intake address to use before any brief exists?”
Tell an agent
Get the intake address for brief {briefId} in {language}.
Look up the intake address for the brief at URL {briefUrl}, language {language}.
GET /api/briefs/intake/items List incoming intake messages · List system intake messages for MCP/UI (#750) #
Ask an LLM
“Which messages have arrived in the brief intake inbox?”
“Can I filter intake messages by sender or by the date they were received?”
Tell an agent
List intake messages with status {status}.
Show intake items from sender {sender} received after {receivedFrom}.
GET /api/briefs/intake/items/{itemId} Read one intake item with its provenance · Read one lossless system intake item with provenance, attachments and work log… #
Ask an LLM
“Can I see the full original intake message with its attachments and work log?”
“Where did a particular intake item come from?”
Tell an agent
Open intake item {itemId} with its attachments and work log.
Show the provenance of intake item {itemId}.
PATCH /api/briefs/intake/items/{itemId}/status Change an intake item's review status · Transition an intake item to IN_REVIEW, IGNORED or REJECTED with an audited… #
Ask an LLM
“How do I mark an intake message as ignored or rejected?”
“Do I have to give a reason when moving an intake item into review?”
Tell an agent
Set intake item {itemId} to {status} because {reason}, idempotency key {key}.
Reject intake item {itemId} with reason {reason} using key {key}.
POST /api/briefs/intake/items/{itemId}/link Link an intake item to a brief · Link an intake item/files to a Brief idempotently (#750) #
Ask an LLM
“How do I attach an incoming intake message and its files to a brief?”
“Can I also tie the intake item to a contact or company when linking it?”
Tell an agent
Link intake item {itemId} to brief {briefId} because {reason}, key {key}.
Attach intake item {itemId} to brief {briefId} and company {companyId}, reason {reason}, key {key}.
POST /api/briefs/intake/items/{itemId}/log Log agent work on an intake item · Append an agent work-log event with intake provenance (#750) #
Ask an LLM
“How does an agent record what it did with an intake message?”
“Can I append a work-log entry to an intake item with source references?”
Tell an agent
Log action {action} on intake item {itemId} with reason {reason}, key {key}.
Append a work-log event {action} to intake item {itemId} for brief {briefId}: {reason} (key {key}).
GET /api/briefs List briefs · List briefs with pagination, search and active/deleted filters #
Ask an LLM
“Which campaign briefs exist in my workspace?”
“Can I search briefs by name and include deleted ones?”
Tell an agent
List my active briefs.
Search briefs for {search}, including deleted ones.
POST /api/briefs Create a brief · Create a new brief #
Ask an LLM
“How do I start a new brief for an outreach campaign?”
“Can a new brief target a specific company list from the start?”
Tell an agent
Create a brief named {name}.
Create brief {name} described as {description} targeting company list {listId}.
GET /api/briefs/{id}/attachments/content Read the content of a brief attachment · Read one Brief attachment as bounded source-backed text/structure/image pages… #
Ask an LLM
“Can I read the text inside a file attached to a brief?”
“How do I page through a long brief attachment or pull out one of its images?”
Tell an agent
Read attachment {attachmentRef} of brief {id}.
Get image {imageRef} from attachment {attachmentRef} on brief {id}.
GET /api/briefs/{id} Get a brief · Get a single brief by id #
Ask an LLM
“What's in a particular brief right now?”
“Can I fetch one brief's full details by its id?”
Tell an agent
Show brief {id}.
Fetch the details of brief {id}.
PATCH /api/briefs/{id} Rename or re-describe a brief · Update brief metadata (name, description, status) #
Ask an LLM
“How do I rename a brief or change its description?”
“Can I deactivate a brief or point it at a different company list?”
Tell an agent
Rename brief {id} to {name}.
Change brief {id}'s target company list to {listId}.
DELETE /api/briefs/{id} Move a brief to trash · Soft-delete a brief with optional reason #
Ask an LLM
“How do I delete a brief I no longer need?”
“Do I need to give a reason when deleting a brief?”
Tell an agent destructive · confirm first
Delete brief {id} with reason {reason}.
Trash brief {id} because {reason}.
PATCH /api/briefs/{id}/content Patch the content body of a brief · Update brief content body (JSON-merge patch). #
Ask an LLM
“How do I edit the personas or examples inside a brief's content?”
“What happens if I try to change a locked section of a brief's content?”
Tell an agent
Apply content patch {patch} to brief {id}.
Merge {patch} into the content of brief {id} with reason {reason}.
PATCH /api/briefs/{id}/variables Update a brief's template variables · Update brief template variables #
Ask an LLM
“How do I change the template variables a brief fills into its copy?”
“Can I patch just a few brief variables without rewriting them all?”
Tell an agent
Patch the template variables of brief {id} with {patch}.
Set brief {id}'s variables to {patch} because {reason}.
PATCH /api/briefs/{id}/locks Lock or unlock sections of a brief · Update brief section locks #
Ask an LLM
“How do I lock a section of a brief so it can't be edited?”
“Can I unlock brief sections that were previously locked?”
Tell an agent
Update the section locks on brief {id}.
Change which sections are locked in brief {id}.
POST /api/briefs/{id}/restore Restore a deleted brief · Restore a soft-deleted brief #
Ask an LLM
“Can I bring back a brief I deleted by mistake?”
“How do I undo a brief deletion?”
Tell an agent
Restore deleted brief {id}.
Undelete brief {id}.
POST /api/briefs/{id}/copy Duplicate a brief · Duplicate an existing brief #
Ask an LLM
“Can I make a copy of an existing brief to start a similar campaign?”
“How do I clone a brief?”
Tell an agent
Duplicate brief {id}.
Make a copy of brief {id}.
GET /api/briefs/{id}/audit Show a brief's change history · List audit entries for a brief #
Ask an LLM
“Who changed a brief and when?”
“Is there an audit trail of edits made to a brief?”
Tell an agent
Show the last {limit} audit entries for brief {id}.
List the change history of brief {id}, up to {limit} entries.
GET /api/briefs/{id}/mail Get a brief's intake mailbox and mail feed · Brief intake email address and mail feed (#744) #
Ask an LLM
“Which emails have been received into a brief's mailbox?”
“Can I see a brief's intake address together with the mail it has collected?”
Tell an agent
Show the mail feed for brief {id} in {language}.
List the latest {limit} emails received by brief {id}, language {language}.
GET /api/briefs/{id}/mail/attachments/{attachmentId}/download Download an attachment from a brief's mail · Download a brief mail attachment (#780) — same tenant guard as the rest of the… #
Ask an LLM
“How do I download a file that was emailed into a brief?”
“Can I fetch an attachment from a brief's mail feed?”
Tell an agent
Download attachment {attachmentId} from brief {id}'s mail.
Save mail attachment {attachmentId} of brief {id}.
PATCH /api/briefs/{id}/intake-alias Change a brief's intake email alias · Change the stable human-readable system intake alias (#756) #
Ask an LLM
“Can I give a brief's intake address a friendlier name?”
“How do I change the readable alias of a brief's intake email?”
Tell an agent
Change the intake alias of brief {id} to {alias} (locale {locale}, language {language}).
Rename brief {id}'s intake address alias to {alias}, locale {locale}, language {language}.
GET /api/briefs/{id}/expert Run the SDR expert review on a brief · Operation-level SDR expert flow: intake provenance → live schema → gaps →… #
Ask an LLM
“What gaps does the SDR expert find in my brief and what does it recommend?”
“Can I get the brief expert's recommendations alongside the live schema?”
Tell an agent
Run the SDR expert flow on brief {id} in {language}.
Get expert {include} for brief {id}, language {language}.
GET /api/briefs/{briefId}/memory List a brief's memory entries · List brief memory entries (decisions, observations, questions, rejected… #
Ask an LLM
“What decisions and open questions have been recorded against a brief?”
“Can I see rejected proposals in a brief's memory, not just active entries?”
Tell an agent
List the active memory entries for brief {briefId}.
Show {kind} memory entries on brief {briefId} across all statuses.
POST /api/briefs/{briefId}/memory Record a decision or note in a brief's memory · Record a memory entry: a decision, an observation, an open question, a REJECTED… #
Ask an LLM
“How do I record a decision or open question on a brief so later agents see it?”
“Can I log a rejected proposal with the reason so it isn't suggested again?”
Tell an agent
Record a memory entry on brief {briefId}.
Add a rejected-proposal note to brief {briefId}'s memory.
POST /api/briefs/{briefId}/memory/{entryId}/resolve Resolve a brief memory entry · Mark a memory entry RESOLVED — leaves the default feed and stops being sent to… #
Ask an LLM
“How do I close out an open question in a brief's memory?”
“Can I stop a memory entry from being sent to the brief expert?”
Tell an agent
Mark memory entry {entryId} on brief {briefId} as resolved.
Resolve entry {entryId} in brief {briefId}'s memory.
POST /api/briefs/{briefId}/memory/migrate-content-review Migrate a brief's review block into memory · #790: one-time migration of the temporary content.review block into memory… #
Ask an LLM
“How do I move the old content review notes on a brief into memory entries?”
“Is it safe to run the content-review migration on a brief more than once?”
Tell an agent
Migrate the content review block of brief {briefId} into memory.
Convert brief {briefId}'s review notes into memory entries.

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/live-direct-marketing-online:live-direct-marketing-online-briefs-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

live-direct-marketing-online-briefs-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: LDM v3 Briefs API
  description: 'Multi-tenant B2B outreach automation platform. Auth: JWT Bearer (15-min) or tenant API key (ldm_*) managed in CRM Settings → API Keys. All tenant-scoped endpoints require the X-Tenant-Id header.'
  version: 1.0.0
  contact: {}
servers:
- url: https://api.live-direct-marketing.online
  description: Production
- url: https://api.dev.live-direct-marketing.online
  description: Development
- url: http://127.0.0.1:3000
  description: Local
tags:
- name: Briefs
paths:
  /api/briefs/schemas:
    get:
      operationId: BriefsController_getSchemas
      parameters:
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Get available brief JSON schemas
      tags:
      - Briefs
      x-required-scope:
      - briefs:read
  /api/briefs/intake:
    get:
      operationId: BriefsController_intake
      parameters:
      - name: briefId
        required: false
        in: query
        description: Existing Brief id. Pass this (or briefUrl) to get scope=brief_direct and the same intakeEmail as Brief UI/expert. Omit only when no Brief exists.
        schema:
          type: string
      - name: briefUrl
        required: false
        in: query
        description: Existing Brief UI URL shaped as /crm/briefs/{briefId}. Pass this (or briefId) for scope=brief_direct; never use workspace intake for an existing Brief.
        schema:
          type: string
      - name: locale
        required: false
        in: query
        schema:
          enum:
          - ru
          - en
          type: string
      - name: accept-language
        required: true
        in: header
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Existing Brief intake address by briefId/briefUrl; omit both only before a…
      tags:
      - Briefs
      x-required-scope:
      - briefs:read
  /api/briefs/intake/items:
    get:
      operationId: BriefsController_listIntakeItems
      parameters:
      - name: paged
        required: false
        in: query
        description: Return {items,hasMore,nextCursor,limit}; legacy false keeps the historical array response.
        schema:
          default: false
          type: boolean
      - name: status
        required: false
        in: query
        schema:
          enum:
          - NEW
          - IN_REVIEW
          - LINKED_TO_BRIEF
          - IGNORED
          - REJECTED
          type: string
      - name: briefId
        required: false
        in: query
        description: Exact Brief id.
        schema:
          maxLength: 128
          type: string
      - name: sender
        required: false
        in: query
        description: Exact canonical sender email (case-insensitive).
        schema:
          maxLength: 320
          format: email
          type: string
      - name: threadId
        required: false
        in: query
        description: Stable threadId returned by this endpoint.
        schema:
          maxLength: 128
          type: string
      - name: receivedFrom
        required: false
        in: query
        description: Inclusive server-receipt lower bound (ISO-8601).
        schema:
          format: date-time
          type: string
      - name: receivedTo
        required: false
        in: query
        description: Inclusive server-receipt upper bound (ISO-8601).
        schema:
          format: date-time
          type: string
      - name: search
        required: false
        in: query
        description: Fuzzy sender/subject search.
        schema:
          maxLength: 500
          type: string
      - name: cursor
        required: false
        in: query
        description: Opaque nextCursor returned by the previous page.
        schema:
          maxLength: 128
          type: string
      - name: limit
        required: false
        in: query
        schema:
          minimum: 1
          maximum: 200
          default: 50
          type: integer
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: List system intake messages for MCP/UI (#750)
      tags:
      - Briefs
      x-required-scope:
      - briefs:read
  /api/briefs/intake/items/{itemId}:
    get:
      operationId: BriefsController_getIntakeItem
      parameters:
      - name: itemId
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Read one lossless system intake item with provenance, attachments and work log…
      tags:
      - Briefs
  /api/briefs/intake/items/{itemId}/status:
    patch:
      operationId: BriefsController_transitionIntakeItem
      parameters:
      - name: itemId
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransitionBriefIntakeItemDto'
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Transition an intake item to IN_REVIEW, IGNORED or REJECTED with an audited…
      tags:
      - Briefs
  /api/briefs/intake/items/{itemId}/link:
    post:
      operationId: BriefsController_linkIntakeItem
      parameters:
      - name: itemId
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LinkBriefIntakeItemDto'
      responses:
        '201':
          description: ''
      security:
      - jwt: []
      summary: Link an intake item/files to a Brief idempotently (#750)
      tags:
      - Briefs
  /api/briefs/intake/items/{itemId}/log:
    post:
      operationId: BriefsController_logIntakeWork
      parameters:
      - name: itemId
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LogBriefIntakeWorkDto'
      responses:
        '201':
          description: ''
      security:
      - jwt: []
      summary: Append an agent work-log event with intake provenance (#750)
      tags:
      - Briefs
  /api/briefs:
    get:
      operationId: BriefsController_findAll
      parameters:
      - name: page
        required: false
        in: query
        schema:
          type: integer
          example: 1
          minimum: 1
      - name: pageSize
        required: false
        in: query
        schema:
          type: integer
          example: 50
          minimum: 1
          maximum: 200
      - name: search
        required: false
        in: query
        schema:
          example: outreach
          type: string
      - name: isActive
        required: false
        in: query
        schema:
          example: true
          type: boolean
      - name: includeDeleted
        required: false
        in: query
        schema:
          example: false
          type: boolean
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: List briefs with pagination, search and active/deleted filters
      tags:
      - Briefs
    post:
      operationId: BriefsController_create
      parameters:
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBriefDto'
      responses:
        '201':
          description: ''
      security:
      - jwt: []
      summary: Create a new brief
      tags:
      - Briefs
  /api/briefs/{id}/attachments/content:
    get:
      operationId: BriefsController_attachmentContent
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: attachmentRef
        required: true
        in: query
        schema:
          example: dialog-attachment:uuid
          type: string
      - name: resource
        required: false
        in: query
        schema:
          enum:
          - text
          - sections
          - tableRows
          - hyperlinks
          - images
          - embeddedObjects
          - parts
          type: string
      - name: cursor
        required: false
        in: query
        schema:
          type: string
      - name: limit
        required: false
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 10
          default: 3
      - name: imageRef
        required: false
        in: query
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Read one Brief attachment as bounded source-backed text/structure/image pages…
      tags:
      - Briefs
  /api/briefs/{id}:
    get:
      operationId: BriefsController_findOne
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Get a single brief by id
      tags:
      - Briefs
    patch:
      operationId: BriefsController_updateMeta
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateBriefMetaDto'
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Update brief metadata (name, description, status)
      tags:
      - Briefs
    delete:
      operationId: BriefsController_softDelete
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: reason
        required: true
        in: query
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Soft-delete a brief with optional reason
      tags:
      - Briefs
  /api/briefs/{id}/content:
    patch:
      operationId: BriefsController_updateContent
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateBriefContentDto'
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Update brief content body (JSON-merge patch).
      tags:
      - Briefs
  /api/briefs/{id}/variables:
    patch:
      operationId: BriefsController_updateVariables
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateBriefVariablesDto'
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Update brief template variables
      tags:
      - Briefs
  /api/briefs/{id}/locks:
    patch:
      operationId: BriefsController_updateLocks
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Update brief section locks
      tags:
      - Briefs
  /api/briefs/{id}/restore:
    post:
      operationId: BriefsController_restore
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '201':
          description: ''
      security:
      - jwt: []
      summary: Restore a soft-deleted brief
      tags:
      - Briefs
  /api/briefs/{id}/copy:
    post:
      operationId: BriefsController_copy
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '201':
          description: ''
      security:
      - jwt: []
      summary: Duplicate an existing brief
      tags:
      - Briefs
  /api/briefs/{id}/audit:
    get:
      operationId: BriefsController_audit
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: limit
        required: true
        in: query
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: List audit entries for a brief
      tags:
      - Briefs
  /api/briefs/{id}/mail:
    get:
      operationId: BriefsController_mail
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: limit
        required: false
        in: query
        schema:
          type: integer
          example: 50
          minimum: 1
          maximum: 200
      - name: locale
        required: false
        in: query
        schema:
          example: ru
          type: string
      - name: accept-language
        required: true
        in: header
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Brief intake email address and mail feed (#744)
      tags:
      - Briefs
  /api/briefs/{id}/mail/attachments/{attachmentId}/download:
    get:
      operationId: BriefsController_downloadMailAttachment
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: attachmentId
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Download a brief mail attachment (#780) — same tenant guard as the rest of the…
      tags:
      - Briefs
  /api/briefs/{id}/intake-alias:
    patch:
      operationId: BriefsController_updateIntakeAlias
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: locale
        required: true
        in: query
        schema:
          type: string
      - name: accept-language
        required: true
        in: header
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateBriefIntakeAliasDto'
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: Change the stable human-readable system intake alias (#756)
      tags:
      - Briefs
  /api/briefs/{id}/expert:
    get:
      operationId: BriefsController_expert
      parameters:
      - name: id
        required: true
        in: path
        schema:
          type: string
      - name: since
        required: false
        in: query
        schema:
          type: string
          format: date-time
      - name: query
        required: false
        in: query
        schema:
          type: string
      - name: limit
        required: false
        in: query
        schema:
          type: integer
          default: 50
          minimum: 1
          maximum: 200
      - name: locale
        required: false
        in: query
        schema:
          enum:
          - ru
          - en
          type: string
      - name: include
        required: false
        in: query
        description: 'Comma-separated: liveSchema, sdrRecommendations, or all. Omit for a compact delta of both.'
        schema:
          type: string
      - name: accept-language
        required: true
        in: header
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: 'Operation-level SDR expert flow: intake provenance → live schema → gaps →…'
      tags:
      - Briefs
  /api/briefs/{briefId}/memory:
    get:
      operationId: BriefMemoryController_list
      parameters:
      - name: briefId
        required: true
        in: path
        schema:
          type: string
      - name: kind
        required: false
        in: query
        schema:
          enum:
          - DECISION
          - OBSERVATION
          - QUESTION
          - REJECTED
          - NOISE
          type: string
      - name: path
        required: false
        in: query
        description: Filter by a content path this entry references, e.g. offer.positioning
        schema:
          type: string
      - name: status
        required: false
        in: query
        schema:
          enum:
          - ACTIVE
          - SUPERSEDED
          - RESOLVED
          type: string
      - name: includeAllStatuses
        required: false
        in: query
        description: Without this, only ACTIVE entries are returned regardless of `status`
        schema:
          type: boolean
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '200':
          description: ''
      security:
      - jwt: []
      summary: List brief memory entries (decisions, observations, questions, rejected…
      tags:
      - Briefs
    post:
      operationId: BriefMemoryController_create
      parameters:
      - name: briefId
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '201':
          description: ''
      security:
      - jwt: []
      summary: 'Record a memory entry: a decision, an observation, an open question, a REJECTED…'
      tags:
      - Briefs
  /api/briefs/{briefId}/memory/{entryId}/resolve:
    post:
      operationId: BriefMemoryController_resolve
      parameters:
      - name: briefId
        required: true
        in: path
        schema:
          type: string
      - name: entryId
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '201':
          description: ''
      security:
      - jwt: []
      summary: Mark a memory entry RESOLVED — leaves the default feed and stops being sent to…
      tags:
      - Briefs
  /api/briefs/{briefId}/memory/migrate-content-review:
    post:
      operationId: BriefMemoryController_migrateContentReview
      parameters:
      - name: briefId
        required: true
        in: path
        schema:
          type: string
      - name: X-Tenant-Id
        in: header
        required: false
        schema:
          type: string
          format: uuid
        description: Tenant UUID — required for all tenant-scoped endpoints
      responses:
        '201':
          description: ''
      security:
      - jwt: []
      summary: '#790: one-time migration of the temporary content.review block into memory…'
      tags:
      - Briefs
components:
  schemas:
    LogBriefIntakeWorkDto:
      type: object
      properties:
        action:
          type: string
          enum:
          - READ
          - FACTS_EXTRACTED
          - CHANGE_PROPOSED
          - CHANGE_APPLIED
          - IGNORED
          - NOTE
        reason:
          type: string
          maxLength: 500
          example: Extracted only facts explicitly supported by the cited customer sources.
        details:
          type: object
          additionalProperties: true
        sourceRefs:
          minItems: 1
          description: 'Required for derived facts/proposals/applied changes; dialog:/dialog-attachment:/intake: refs only.'
          type: array
          items:
            type: string
        briefId:
          type: string
          example: brief-id
        idempotencyKey:
          type: string
          maxLength: 128
          example: intake-item-123-read-v1
      required:
      - action
      - reason
      - idempotencyKey
    UpdateBriefIntakeAliasDto:
      type: object
      properties:
        alias:
          type: string
          minLength: 8
          maxLength: 64
          pattern: /^brief-[a-z0-9](?:[a-z0-9-]*[a-z0-9])$/
      required:
      - alias
    UpdateBriefMetaDto:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        isActive:
          type: boolean
        targetCompanyListId:
          type:
          - object
          - 'null'
          description: '#847: целевой список проекта. `null` — снять связь явно.

            Без этого поля читатель (`resolveTargetList`) был бы механизмом без

            вызывающего: связь стала бы исправимой, но не исправленной.'
        reason:
          type: string
    UpdateBriefContentDto:
      type: object
      properties:
        patch:
          type: object
          description: Partial JSON-merge patch for `content`. Top-level keys whose path is locked (locks[key] === true) are rejected with 423. Merged result is validated against brief-content-v1.2.
        reason:
          type: string
      required:
      - patch
    CreateBriefDto:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        isActive:
          type: boolean
        content:
          type: object
          description: Initial content, validated against brief-content-v1.2 before save.
        variables:
          type: object
        locks:
          type: object
          description: Map of section paths to boolean lock state.
        targetCompanyListId:
          type:
          - string
          - 'null'
          description: Target company list ID. Can be a string or null.
      required:
      - name
    LinkBriefIntakeItemDto:
      type: object
      properties:
        briefId:
          type: string
          example: brief-id
        contactId:
          type:
          - object
          - 'null'
          description: Existing customer Contact, or null to clear a wrong association.
        companyId:
          type:
          - object
          - 'null'
          description: Existing customer Company, or null to clear a wrong association.
        reason:
          type: string
          maxLength: 500
          example: Human confirmed that these materials belong to this brief.
        idempotencyKey:
          type: string
          maxLength: 128
          example: link-intake-item-123-to-brief-id-v1
      required:
      - briefId
      - reason
      - idempotencyKey
    TransitionBriefIntakeItemDto:
      type: object
      properties:
        status:
          type: string
          enum:
          - IN_REVIEW
          - IGNORED
          - REJECTED
          example: IN_REVIEW
        reason:
          type: string
          maxLength: 500
          example: Operator reviewed the sender and attachments.
        idempotencyKey:
          type: string
          maxLength: 128
          example: review-intake-item-123-v1
      required:
      - status
      - reason
      - idempotencyKey
    UpdateBriefVariablesDto:
      type: object
      properties:
        patch:
          type: object
          description: Partial JSON-merge patch for `variables`.
        reason:
          type: string
      required:
      - patch
  securitySchemes:
    jwt:
      scheme: bearer
      bearerFormat: JWT
      type: http
      description: JWT access token from /auth/login (Bearer <token>)
    tenant-api-key:
      scheme: bearer
      bearerFormat: JWT
      type: http
      description: Tenant API key (Bearer ldm_*) for MCP/A2A clients. Issued via CRM Settings → API Keys.
    rpa-service:
      scheme: bearer
      bearerFormat: JWT
      type: http
      description: Dedicated RPA service key. No tenant API-key or query-key authentication.