# Phone Numbers

## List phone numbers

`client.PhoneNumbers.List(ctx) (*PhoneNumberListResponse, error)`

**get** `/v3/phone_numbers`

Returns all phone numbers assigned to the authenticated partner.
Use this endpoint to discover which phone numbers are available for
use as the `from` field when creating a chat, listing chats, or sending a voice memo.

### Returns

- `type PhoneNumberListResponse struct{…}`

  - `PhoneNumbers []PhoneNumberListResponsePhoneNumber`

    List of phone numbers assigned to the partner

    - `ID string`

      Unique identifier for the phone number

    - `PhoneNumber string`

      Phone number in E.164 format

    - `Reputation PhoneNumberListResponsePhoneNumberReputation`

      **[BETA]** Current reputation for a phone line. Always present — lines start at `HEALTHY` and may shift based on aggregate engagement and delivery signals across all conversations on the line.

      Unlike chat health, line reputation does not include `opted_out` — opt-out applies to individual recipients, not the whole line.

      See the [Phone Reputation guide](/channel/imessage/guides/phone-numbers/phone-reputation) for what each status means and how to react.

      - `DocURL string`

        Deep-link to the relevant section of the Phone Reputation guide for this status.

      - `Status string`

        Current reputation of this phone line.

        - `HEALTHY` — The line is in good standing. Send normally.
        - `AT_RISK` — Warning signs on the line: engagement is low across many of its conversations, or it's starting too many brand-new conversations in a single day — and a spike in send volume can add to either. Slow the line's send pace, avoid opening many new conversations at once, and review your messaging patterns.
        - `CRITICAL` — Strong signals that messages from this line aren't landing well. Pause outbound on the line until it recovers.

        Defaults to `HEALTHY` for lines that have not yet been scored.

        - `const PhoneNumberListResponsePhoneNumberReputationStatusHealthy PhoneNumberListResponsePhoneNumberReputationStatus = "HEALTHY"`

        - `const PhoneNumberListResponsePhoneNumberReputationStatusAtRisk PhoneNumberListResponsePhoneNumberReputationStatus = "AT_RISK"`

        - `const PhoneNumberListResponsePhoneNumberReputationStatusCritical PhoneNumberListResponsePhoneNumberReputationStatus = "CRITICAL"`

    - `ForwardingNumber string`

      The forwarding number associated with this phone number, in E.164 format. Null when no forwarding number is configured.

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/linq-team/linq-go"
  "github.com/linq-team/linq-go/option"
)

func main() {
  client := linqgo.NewClient(
    option.WithAPIKey("My API Key"),
  )
  phoneNumbers, err := client.PhoneNumbers.List(context.TODO())
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", phoneNumbers.PhoneNumbers)
}
```

#### Response

```json
{
  "phone_numbers": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "phone_number": "+12025551234",
      "forwarding_number": "+12025559999",
      "reputation": {
        "status": "HEALTHY",
        "doc_url": "https://docs.linqapp.com/channel/imessage/guides/phone-numbers/phone-reputation#healthy"
      }
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "phone_number": "+12025559876",
      "forwarding_number": null,
      "reputation": {
        "status": "AT_RISK",
        "doc_url": "https://docs.linqapp.com/channel/imessage/guides/phone-numbers/phone-reputation#at-risk"
      }
    }
  ]
}
```

## Update a phone number

`client.PhoneNumbers.Update(ctx, phoneNumberID, body) (*PhoneNumberUpdateResponse, error)`

**put** `/v3/phone_numbers/{phoneNumberId}`

Updates the forwarding number for a phone number. The forwarding number is where inbound calls will be forwarded to.

Pass an empty string to clear the forwarding number.

### Parameters

- `phoneNumberID string`

- `body PhoneNumberUpdateParams`

  - `ForwardingNumber param.Field[string]`

    The forwarding number in E.164 format. Set to null or empty string to clear.

### Returns

- `type PhoneNumberUpdateResponse struct{…}`

  - `ID string`

    Unique identifier for the phone number

  - `ForwardingNumber string`

    The forwarding number after the update. Null when cleared.

  - `PhoneNumber string`

    Phone number in E.164 format

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/linq-team/linq-go"
  "github.com/linq-team/linq-go/option"
)

func main() {
  client := linqgo.NewClient(
    option.WithAPIKey("My API Key"),
  )
  phoneNumber, err := client.PhoneNumbers.Update(
    context.TODO(),
    "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    linqgo.PhoneNumberUpdateParams{
      ForwardingNumber: linqgo.String("+12025559999"),
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", phoneNumber.ID)
}
```

#### Response

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "phone_number": "+12025551234",
  "forwarding_number": "+12025559999"
}
```

## Start a line reputation audit

`client.PhoneNumbers.StartReputationAudit(ctx, phoneNumber) (*ReputationAuditStarted, error)`

**post** `/v3/phone_numbers/{phoneNumber}/reputation_audit`

Starts an asynchronous reputation audit for a line and returns an
`audit_id`. Poll the GET endpoint for the result.

Rate limited per line: only one audit may run at a time. Starting one
while another is still running returns `202` with the running audit's
`audit_id` rather than an error, so a retried start picks that audit
back up instead of losing it — poll the id you were given.

Once an audit finishes, a new one can't be started for the same line
until a cooldown elapses (`429`, with `Retry-After` carrying the wait).
Keep the `audit_id` from the original `202`: it stays readable on the
GET endpoint for 24 hours, and the cooldown response does not repeat
it.

### Parameters

- `phoneNumber string`

### Returns

- `type ReputationAuditStarted struct{…}`

  - `AuditID string`

    Identifier for this audit. Poll `GET /v3/phone_numbers/{phoneNumber}/reputation_audit/{auditId}` until `status` is `complete` or `error`.

  - `Status ReputationAuditStartedStatus`

    A newly started audit is `pending`.

    - `const ReputationAuditStartedStatusPending ReputationAuditStartedStatus = "pending"`

    - `const ReputationAuditStartedStatusComplete ReputationAuditStartedStatus = "complete"`

    - `const ReputationAuditStartedStatusError ReputationAuditStartedStatus = "error"`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/linq-team/linq-go"
  "github.com/linq-team/linq-go/option"
)

func main() {
  client := linqgo.NewClient(
    option.WithAPIKey("My API Key"),
  )
  reputationAuditStarted, err := client.PhoneNumbers.StartReputationAudit(context.TODO(), "phoneNumber")
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", reputationAuditStarted.AuditID)
}
```

#### Response

```json
{
  "audit_id": "audit_id",
  "status": "pending"
}
```

## Get a line reputation audit

`client.PhoneNumbers.GetReputationAudit(ctx, auditID, query) (*ReputationAudit, error)`

**get** `/v3/phone_numbers/{phoneNumber}/reputation_audit/{auditId}`

Returns the audit's status and, once complete, the report. Audits are
scoped to the line in the URL — an `auditId` started on a different
line returns `404`.

### Parameters

- `auditID string`

- `query PhoneNumberGetReputationAuditParams`

  - `PhoneNumber param.Field[string]`

    The line in E.164 format.

### Returns

- `type ReputationAudit struct{…}`

  - `AuditID string`

  - `Status ReputationAuditStatus`

    `pending` until the report is ready — poll until `complete` or `error`.

    - `const ReputationAuditStatusPending ReputationAuditStatus = "pending"`

    - `const ReputationAuditStatusComplete ReputationAuditStatus = "complete"`

    - `const ReputationAuditStatusError ReputationAuditStatus = "error"`

  - `Error string`

    Present only when `status` is `error`. Short, generic reason safe to display.

  - `GeneratedAt Time`

    When the report was generated; signals reflect the line at this moment.

  - `Phone string`

    The line audited, E.164.

  - `Report ReputationReport`

    Present only when `status` is `complete`.

    - `ActionItems []ReputationActionItem`

      Ordered by `priority`; 1 = do first.

      - `Detail string`

      - `ExpectedImpact ReputationActionItemExpectedImpact`

        - `const ReputationActionItemExpectedImpactHigh ReputationActionItemExpectedImpact = "high"`

        - `const ReputationActionItemExpectedImpactMedium ReputationActionItemExpectedImpact = "medium"`

        - `const ReputationActionItemExpectedImpactLow ReputationActionItemExpectedImpact = "low"`

      - `Priority int64`

        1 = do first

      - `Title string`

    - `Drivers []ReputationDriver`

      Ranked, highest impact first.

      - `Key ReputationDriverKey`

        Stable driver-category identifier — what is dragging the line, or one
        of its conversations, down.

        - `low_engagement` — The conversation is one-sided: several messages
          sent, few or no replies back. Pause or rework outreach where
          recipients are not replying, and lead with messages that invite a
          response. Conversation-level: it appears on
          `evidence.unhealthy_chats[].driver_keys`, never in `drivers`.
        - `overall_conversation_health` — A large share of the line's active
          conversations are trending unhealthy. Fix the unhealthy conversations
          first — review their content and timing, and whether recipients are
          engaging.
        - `volume_spike` — The line's daily sending volume jumped far above its
          own normal level while few recipients were replying, or exceeded the
          recommended daily volume for a single line. Ramp volume gradually
          instead of spiking, prioritize people who have already engaged with
          you, and spread sustained high volume across additional lines.
        - `new_conversation_rate` — The line is starting too many brand-new
          conversations in a single day. Spread new conversations out over time
          instead of starting many at once.
        - `opt_out_handling` — Recipients asked this line to stop. Honor every
          stop request immediately: send nothing further to that recipient
          unless they opt back in. Every send to them is rejected with `403`
          (error code `2024`), including a final courtesy message — to send
          one telling them they can reply to resume, set
          `override_optout: true` on that single request.
        - `flagged` — The line is currently restricted and its messages may not
          be reaching recipients. Move active traffic to a healthy line now,
          and let this one recover before sending more.
        - `other` — Fallback for a signal without dedicated partner copy.

        - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

        - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

        - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

        - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

        - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

        - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

        - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

      - `Metric string`

        A specific observed figure when available; otherwise a short qualitative note.

      - `Summary string`

        One plain-English sentence.

    - `Evidence ReputationEvidence`

      The specific conversations behind the drivers, so partners can verify every claim against their own send logs. Each `chat_id` can be fetched via `GET /v3/chats/{chatId}` — its current health appears there.

      - `OptOutChats []ReputationOptOutChat`

        Worst first — most messages sent after the stop request; honor these immediately.

        - `ChatID string`

        - `MessagesAfterStop int64`

          Outbound messages sent after the recipient asked to stop.

      - `UnhealthyChats []ReputationUnhealthyChat`

        Up to 15, worst first.

        - `ChatID string`

        - `DriverKeys []ReputationDriverKey`

          What is dragging this conversation down, in the same vocabulary as the report's drivers. Each key's meaning and the fix for it are documented on `ReputationDriverKey`.

          - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

          - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

          - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

          - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

          - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

          - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

          - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

        - `Status ReputationUnhealthyChatStatus`

          The conversation's current health — the same value `GET /v3/chats/{chatId}` reports for it.

          - `const ReputationUnhealthyChatStatusAtRisk ReputationUnhealthyChatStatus = "AT_RISK"`

          - `const ReputationUnhealthyChatStatusCritical ReputationUnhealthyChatStatus = "CRITICAL"`

          - `const ReputationUnhealthyChatStatusOptedOut ReputationUnhealthyChatStatus = "OPTED_OUT"`

    - `PrimaryDriver string`

      The `key` of the most important driver. Empty string when the line has nothing to act on — the report then carries a single reassurance action item. Its values are the `ReputationDriverKey` vocabulary — see that schema for what each means and what to do about it.

    - `Severity ReputationReportSeverity`

      Current reputation of this phone line.

      - `HEALTHY` — The line is in good standing. Send normally.
      - `AT_RISK` — Warning signs on the line: engagement is low across many of its conversations, or it's starting too many brand-new conversations in a single day — and a spike in send volume can add to either. Slow the line's send pace, avoid opening many new conversations at once, and review your messaging patterns.
      - `CRITICAL` — Strong signals that messages from this line aren't landing well. Pause outbound on the line until it recovers.

      Defaults to `HEALTHY` for lines that have not yet been scored.

      - `const ReputationReportSeverityHealthy ReputationReportSeverity = "HEALTHY"`

      - `const ReputationReportSeverityAtRisk ReputationReportSeverity = "AT_RISK"`

      - `const ReputationReportSeverityCritical ReputationReportSeverity = "CRITICAL"`

    - `SummaryMarkdown string`

      Deterministic markdown rendering of this report, suitable for feeding directly to automated systems and AI agents as investigation context. Rendered from the structured fields above, which remain the source of truth.

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/linq-team/linq-go"
  "github.com/linq-team/linq-go/option"
)

func main() {
  client := linqgo.NewClient(
    option.WithAPIKey("My API Key"),
  )
  reputationAudit, err := client.PhoneNumbers.GetReputationAudit(
    context.TODO(),
    "auditId",
    linqgo.PhoneNumberGetReputationAuditParams{
      PhoneNumber: "phoneNumber",
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", reputationAudit.AuditID)
}
```

#### Response

```json
{
  "audit_id": "audit_id",
  "status": "pending",
  "error": "error",
  "generated_at": "2019-12-27T18:11:19.117Z",
  "phone": "phone",
  "report": {
    "action_items": [
      {
        "detail": "detail",
        "expected_impact": "high",
        "priority": 0,
        "title": "title"
      }
    ],
    "drivers": [
      {
        "key": "low_engagement",
        "metric": "metric",
        "summary": "summary"
      }
    ],
    "evidence": {
      "opt_out_chats": [
        {
          "chat_id": "chat_id",
          "messages_after_stop": 0
        }
      ],
      "unhealthy_chats": [
        {
          "chat_id": "chat_id",
          "driver_keys": [
            "low_engagement"
          ],
          "status": "AT_RISK"
        }
      ]
    },
    "primary_driver": "primary_driver",
    "severity": "HEALTHY",
    "summary_markdown": "## Line reputation summary\n\n**Status:** AT_RISK\n..."
  }
}
```

## Domain Types

### Reputation Action Item

- `type ReputationActionItem struct{…}`

  - `Detail string`

  - `ExpectedImpact ReputationActionItemExpectedImpact`

    - `const ReputationActionItemExpectedImpactHigh ReputationActionItemExpectedImpact = "high"`

    - `const ReputationActionItemExpectedImpactMedium ReputationActionItemExpectedImpact = "medium"`

    - `const ReputationActionItemExpectedImpactLow ReputationActionItemExpectedImpact = "low"`

  - `Priority int64`

    1 = do first

  - `Title string`

### Reputation Audit

- `type ReputationAudit struct{…}`

  - `AuditID string`

  - `Status ReputationAuditStatus`

    `pending` until the report is ready — poll until `complete` or `error`.

    - `const ReputationAuditStatusPending ReputationAuditStatus = "pending"`

    - `const ReputationAuditStatusComplete ReputationAuditStatus = "complete"`

    - `const ReputationAuditStatusError ReputationAuditStatus = "error"`

  - `Error string`

    Present only when `status` is `error`. Short, generic reason safe to display.

  - `GeneratedAt Time`

    When the report was generated; signals reflect the line at this moment.

  - `Phone string`

    The line audited, E.164.

  - `Report ReputationReport`

    Present only when `status` is `complete`.

    - `ActionItems []ReputationActionItem`

      Ordered by `priority`; 1 = do first.

      - `Detail string`

      - `ExpectedImpact ReputationActionItemExpectedImpact`

        - `const ReputationActionItemExpectedImpactHigh ReputationActionItemExpectedImpact = "high"`

        - `const ReputationActionItemExpectedImpactMedium ReputationActionItemExpectedImpact = "medium"`

        - `const ReputationActionItemExpectedImpactLow ReputationActionItemExpectedImpact = "low"`

      - `Priority int64`

        1 = do first

      - `Title string`

    - `Drivers []ReputationDriver`

      Ranked, highest impact first.

      - `Key ReputationDriverKey`

        Stable driver-category identifier — what is dragging the line, or one
        of its conversations, down.

        - `low_engagement` — The conversation is one-sided: several messages
          sent, few or no replies back. Pause or rework outreach where
          recipients are not replying, and lead with messages that invite a
          response. Conversation-level: it appears on
          `evidence.unhealthy_chats[].driver_keys`, never in `drivers`.
        - `overall_conversation_health` — A large share of the line's active
          conversations are trending unhealthy. Fix the unhealthy conversations
          first — review their content and timing, and whether recipients are
          engaging.
        - `volume_spike` — The line's daily sending volume jumped far above its
          own normal level while few recipients were replying, or exceeded the
          recommended daily volume for a single line. Ramp volume gradually
          instead of spiking, prioritize people who have already engaged with
          you, and spread sustained high volume across additional lines.
        - `new_conversation_rate` — The line is starting too many brand-new
          conversations in a single day. Spread new conversations out over time
          instead of starting many at once.
        - `opt_out_handling` — Recipients asked this line to stop. Honor every
          stop request immediately: send nothing further to that recipient
          unless they opt back in. Every send to them is rejected with `403`
          (error code `2024`), including a final courtesy message — to send
          one telling them they can reply to resume, set
          `override_optout: true` on that single request.
        - `flagged` — The line is currently restricted and its messages may not
          be reaching recipients. Move active traffic to a healthy line now,
          and let this one recover before sending more.
        - `other` — Fallback for a signal without dedicated partner copy.

        - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

        - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

        - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

        - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

        - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

        - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

        - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

      - `Metric string`

        A specific observed figure when available; otherwise a short qualitative note.

      - `Summary string`

        One plain-English sentence.

    - `Evidence ReputationEvidence`

      The specific conversations behind the drivers, so partners can verify every claim against their own send logs. Each `chat_id` can be fetched via `GET /v3/chats/{chatId}` — its current health appears there.

      - `OptOutChats []ReputationOptOutChat`

        Worst first — most messages sent after the stop request; honor these immediately.

        - `ChatID string`

        - `MessagesAfterStop int64`

          Outbound messages sent after the recipient asked to stop.

      - `UnhealthyChats []ReputationUnhealthyChat`

        Up to 15, worst first.

        - `ChatID string`

        - `DriverKeys []ReputationDriverKey`

          What is dragging this conversation down, in the same vocabulary as the report's drivers. Each key's meaning and the fix for it are documented on `ReputationDriverKey`.

          - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

          - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

          - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

          - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

          - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

          - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

          - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

        - `Status ReputationUnhealthyChatStatus`

          The conversation's current health — the same value `GET /v3/chats/{chatId}` reports for it.

          - `const ReputationUnhealthyChatStatusAtRisk ReputationUnhealthyChatStatus = "AT_RISK"`

          - `const ReputationUnhealthyChatStatusCritical ReputationUnhealthyChatStatus = "CRITICAL"`

          - `const ReputationUnhealthyChatStatusOptedOut ReputationUnhealthyChatStatus = "OPTED_OUT"`

    - `PrimaryDriver string`

      The `key` of the most important driver. Empty string when the line has nothing to act on — the report then carries a single reassurance action item. Its values are the `ReputationDriverKey` vocabulary — see that schema for what each means and what to do about it.

    - `Severity ReputationReportSeverity`

      Current reputation of this phone line.

      - `HEALTHY` — The line is in good standing. Send normally.
      - `AT_RISK` — Warning signs on the line: engagement is low across many of its conversations, or it's starting too many brand-new conversations in a single day — and a spike in send volume can add to either. Slow the line's send pace, avoid opening many new conversations at once, and review your messaging patterns.
      - `CRITICAL` — Strong signals that messages from this line aren't landing well. Pause outbound on the line until it recovers.

      Defaults to `HEALTHY` for lines that have not yet been scored.

      - `const ReputationReportSeverityHealthy ReputationReportSeverity = "HEALTHY"`

      - `const ReputationReportSeverityAtRisk ReputationReportSeverity = "AT_RISK"`

      - `const ReputationReportSeverityCritical ReputationReportSeverity = "CRITICAL"`

    - `SummaryMarkdown string`

      Deterministic markdown rendering of this report, suitable for feeding directly to automated systems and AI agents as investigation context. Rendered from the structured fields above, which remain the source of truth.

### Reputation Audit Started

- `type ReputationAuditStarted struct{…}`

  - `AuditID string`

    Identifier for this audit. Poll `GET /v3/phone_numbers/{phoneNumber}/reputation_audit/{auditId}` until `status` is `complete` or `error`.

  - `Status ReputationAuditStartedStatus`

    A newly started audit is `pending`.

    - `const ReputationAuditStartedStatusPending ReputationAuditStartedStatus = "pending"`

    - `const ReputationAuditStartedStatusComplete ReputationAuditStartedStatus = "complete"`

    - `const ReputationAuditStartedStatusError ReputationAuditStartedStatus = "error"`

### Reputation Driver

- `type ReputationDriver struct{…}`

  - `Key ReputationDriverKey`

    Stable driver-category identifier — what is dragging the line, or one
    of its conversations, down.

    - `low_engagement` — The conversation is one-sided: several messages
      sent, few or no replies back. Pause or rework outreach where
      recipients are not replying, and lead with messages that invite a
      response. Conversation-level: it appears on
      `evidence.unhealthy_chats[].driver_keys`, never in `drivers`.
    - `overall_conversation_health` — A large share of the line's active
      conversations are trending unhealthy. Fix the unhealthy conversations
      first — review their content and timing, and whether recipients are
      engaging.
    - `volume_spike` — The line's daily sending volume jumped far above its
      own normal level while few recipients were replying, or exceeded the
      recommended daily volume for a single line. Ramp volume gradually
      instead of spiking, prioritize people who have already engaged with
      you, and spread sustained high volume across additional lines.
    - `new_conversation_rate` — The line is starting too many brand-new
      conversations in a single day. Spread new conversations out over time
      instead of starting many at once.
    - `opt_out_handling` — Recipients asked this line to stop. Honor every
      stop request immediately: send nothing further to that recipient
      unless they opt back in. Every send to them is rejected with `403`
      (error code `2024`), including a final courtesy message — to send
      one telling them they can reply to resume, set
      `override_optout: true` on that single request.
    - `flagged` — The line is currently restricted and its messages may not
      be reaching recipients. Move active traffic to a healthy line now,
      and let this one recover before sending more.
    - `other` — Fallback for a signal without dedicated partner copy.

    - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

    - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

    - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

    - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

    - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

    - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

    - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

  - `Metric string`

    A specific observed figure when available; otherwise a short qualitative note.

  - `Summary string`

    One plain-English sentence.

### Reputation Driver Key

- `type ReputationDriverKey string`

  Stable driver-category identifier — what is dragging the line, or one
  of its conversations, down.

  - `low_engagement` — The conversation is one-sided: several messages
    sent, few or no replies back. Pause or rework outreach where
    recipients are not replying, and lead with messages that invite a
    response. Conversation-level: it appears on
    `evidence.unhealthy_chats[].driver_keys`, never in `drivers`.
  - `overall_conversation_health` — A large share of the line's active
    conversations are trending unhealthy. Fix the unhealthy conversations
    first — review their content and timing, and whether recipients are
    engaging.
  - `volume_spike` — The line's daily sending volume jumped far above its
    own normal level while few recipients were replying, or exceeded the
    recommended daily volume for a single line. Ramp volume gradually
    instead of spiking, prioritize people who have already engaged with
    you, and spread sustained high volume across additional lines.
  - `new_conversation_rate` — The line is starting too many brand-new
    conversations in a single day. Spread new conversations out over time
    instead of starting many at once.
  - `opt_out_handling` — Recipients asked this line to stop. Honor every
    stop request immediately: send nothing further to that recipient
    unless they opt back in. Every send to them is rejected with `403`
    (error code `2024`), including a final courtesy message — to send
    one telling them they can reply to resume, set
    `override_optout: true` on that single request.
  - `flagged` — The line is currently restricted and its messages may not
    be reaching recipients. Move active traffic to a healthy line now,
    and let this one recover before sending more.
  - `other` — Fallback for a signal without dedicated partner copy.

  - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

  - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

  - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

  - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

  - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

  - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

  - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

### Reputation Evidence

- `type ReputationEvidence struct{…}`

  The specific conversations behind the drivers, so partners can verify every claim against their own send logs. Each `chat_id` can be fetched via `GET /v3/chats/{chatId}` — its current health appears there.

  - `OptOutChats []ReputationOptOutChat`

    Worst first — most messages sent after the stop request; honor these immediately.

    - `ChatID string`

    - `MessagesAfterStop int64`

      Outbound messages sent after the recipient asked to stop.

  - `UnhealthyChats []ReputationUnhealthyChat`

    Up to 15, worst first.

    - `ChatID string`

    - `DriverKeys []ReputationDriverKey`

      What is dragging this conversation down, in the same vocabulary as the report's drivers. Each key's meaning and the fix for it are documented on `ReputationDriverKey`.

      - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

      - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

      - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

      - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

      - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

      - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

      - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

    - `Status ReputationUnhealthyChatStatus`

      The conversation's current health — the same value `GET /v3/chats/{chatId}` reports for it.

      - `const ReputationUnhealthyChatStatusAtRisk ReputationUnhealthyChatStatus = "AT_RISK"`

      - `const ReputationUnhealthyChatStatusCritical ReputationUnhealthyChatStatus = "CRITICAL"`

      - `const ReputationUnhealthyChatStatusOptedOut ReputationUnhealthyChatStatus = "OPTED_OUT"`

### Reputation Opt Out Chat

- `type ReputationOptOutChat struct{…}`

  - `ChatID string`

  - `MessagesAfterStop int64`

    Outbound messages sent after the recipient asked to stop.

### Reputation Report

- `type ReputationReport struct{…}`

  - `ActionItems []ReputationActionItem`

    Ordered by `priority`; 1 = do first.

    - `Detail string`

    - `ExpectedImpact ReputationActionItemExpectedImpact`

      - `const ReputationActionItemExpectedImpactHigh ReputationActionItemExpectedImpact = "high"`

      - `const ReputationActionItemExpectedImpactMedium ReputationActionItemExpectedImpact = "medium"`

      - `const ReputationActionItemExpectedImpactLow ReputationActionItemExpectedImpact = "low"`

    - `Priority int64`

      1 = do first

    - `Title string`

  - `Drivers []ReputationDriver`

    Ranked, highest impact first.

    - `Key ReputationDriverKey`

      Stable driver-category identifier — what is dragging the line, or one
      of its conversations, down.

      - `low_engagement` — The conversation is one-sided: several messages
        sent, few or no replies back. Pause or rework outreach where
        recipients are not replying, and lead with messages that invite a
        response. Conversation-level: it appears on
        `evidence.unhealthy_chats[].driver_keys`, never in `drivers`.
      - `overall_conversation_health` — A large share of the line's active
        conversations are trending unhealthy. Fix the unhealthy conversations
        first — review their content and timing, and whether recipients are
        engaging.
      - `volume_spike` — The line's daily sending volume jumped far above its
        own normal level while few recipients were replying, or exceeded the
        recommended daily volume for a single line. Ramp volume gradually
        instead of spiking, prioritize people who have already engaged with
        you, and spread sustained high volume across additional lines.
      - `new_conversation_rate` — The line is starting too many brand-new
        conversations in a single day. Spread new conversations out over time
        instead of starting many at once.
      - `opt_out_handling` — Recipients asked this line to stop. Honor every
        stop request immediately: send nothing further to that recipient
        unless they opt back in. Every send to them is rejected with `403`
        (error code `2024`), including a final courtesy message — to send
        one telling them they can reply to resume, set
        `override_optout: true` on that single request.
      - `flagged` — The line is currently restricted and its messages may not
        be reaching recipients. Move active traffic to a healthy line now,
        and let this one recover before sending more.
      - `other` — Fallback for a signal without dedicated partner copy.

      - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

      - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

      - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

      - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

      - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

      - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

      - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

    - `Metric string`

      A specific observed figure when available; otherwise a short qualitative note.

    - `Summary string`

      One plain-English sentence.

  - `Evidence ReputationEvidence`

    The specific conversations behind the drivers, so partners can verify every claim against their own send logs. Each `chat_id` can be fetched via `GET /v3/chats/{chatId}` — its current health appears there.

    - `OptOutChats []ReputationOptOutChat`

      Worst first — most messages sent after the stop request; honor these immediately.

      - `ChatID string`

      - `MessagesAfterStop int64`

        Outbound messages sent after the recipient asked to stop.

    - `UnhealthyChats []ReputationUnhealthyChat`

      Up to 15, worst first.

      - `ChatID string`

      - `DriverKeys []ReputationDriverKey`

        What is dragging this conversation down, in the same vocabulary as the report's drivers. Each key's meaning and the fix for it are documented on `ReputationDriverKey`.

        - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

        - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

        - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

        - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

        - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

        - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

        - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

      - `Status ReputationUnhealthyChatStatus`

        The conversation's current health — the same value `GET /v3/chats/{chatId}` reports for it.

        - `const ReputationUnhealthyChatStatusAtRisk ReputationUnhealthyChatStatus = "AT_RISK"`

        - `const ReputationUnhealthyChatStatusCritical ReputationUnhealthyChatStatus = "CRITICAL"`

        - `const ReputationUnhealthyChatStatusOptedOut ReputationUnhealthyChatStatus = "OPTED_OUT"`

  - `PrimaryDriver string`

    The `key` of the most important driver. Empty string when the line has nothing to act on — the report then carries a single reassurance action item. Its values are the `ReputationDriverKey` vocabulary — see that schema for what each means and what to do about it.

  - `Severity ReputationReportSeverity`

    Current reputation of this phone line.

    - `HEALTHY` — The line is in good standing. Send normally.
    - `AT_RISK` — Warning signs on the line: engagement is low across many of its conversations, or it's starting too many brand-new conversations in a single day — and a spike in send volume can add to either. Slow the line's send pace, avoid opening many new conversations at once, and review your messaging patterns.
    - `CRITICAL` — Strong signals that messages from this line aren't landing well. Pause outbound on the line until it recovers.

    Defaults to `HEALTHY` for lines that have not yet been scored.

    - `const ReputationReportSeverityHealthy ReputationReportSeverity = "HEALTHY"`

    - `const ReputationReportSeverityAtRisk ReputationReportSeverity = "AT_RISK"`

    - `const ReputationReportSeverityCritical ReputationReportSeverity = "CRITICAL"`

  - `SummaryMarkdown string`

    Deterministic markdown rendering of this report, suitable for feeding directly to automated systems and AI agents as investigation context. Rendered from the structured fields above, which remain the source of truth.

### Reputation Unhealthy Chat

- `type ReputationUnhealthyChat struct{…}`

  - `ChatID string`

  - `DriverKeys []ReputationDriverKey`

    What is dragging this conversation down, in the same vocabulary as the report's drivers. Each key's meaning and the fix for it are documented on `ReputationDriverKey`.

    - `const ReputationDriverKeyLowEngagement ReputationDriverKey = "low_engagement"`

    - `const ReputationDriverKeyOverallConversationHealth ReputationDriverKey = "overall_conversation_health"`

    - `const ReputationDriverKeyVolumeSpike ReputationDriverKey = "volume_spike"`

    - `const ReputationDriverKeyNewConversationRate ReputationDriverKey = "new_conversation_rate"`

    - `const ReputationDriverKeyOptOutHandling ReputationDriverKey = "opt_out_handling"`

    - `const ReputationDriverKeyFlagged ReputationDriverKey = "flagged"`

    - `const ReputationDriverKeyOther ReputationDriverKey = "other"`

  - `Status ReputationUnhealthyChatStatus`

    The conversation's current health — the same value `GET /v3/chats/{chatId}` reports for it.

    - `const ReputationUnhealthyChatStatusAtRisk ReputationUnhealthyChatStatus = "AT_RISK"`

    - `const ReputationUnhealthyChatStatusCritical ReputationUnhealthyChatStatus = "CRITICAL"`

    - `const ReputationUnhealthyChatStatusOptedOut ReputationUnhealthyChatStatus = "OPTED_OUT"`
