---
title: "SEND SAFETY PREFLIGHT (CANONICAL). Read-only factual check before any send. eligible_targets is the FINAL safe cohort: it already applies BOTH outreach-local safety and GLOBAL RECIPIENT SAFETY across every Outreach in the workspace, resolved by normalized email. You never need to call another endpoint or union blockers yourself. Per recipient, local_blockers and global_blockers are exposed for diagnostic transparency only. Global blocker codes: global_hard_bounce, global_unsubscribe, global_active_human_conversation, global_meaningful_reply_requires_individual_handling, global_duplicate_recent_send, global_existing_waiting_loop, global_suppression, global_identity_ambiguity. A hard bounce or unsubscribe recorded in ANY Outreach is workspace-level address evidence and blocks reuse elsewhere; an active human conversation discovered in another Outreach blocks generic campaign contact. Identity is never fuzzily merged: an ambiguous address is blocked, not merged. The response also reports autonomous_send_budget, which is INFORMATIONAL only — the budget is enforced transactionally when an execution is recorded. Forbiz never sends; this call changes nothing."
method: GET
path: "/outreach/{id}/preflight"
---

# SEND SAFETY PREFLIGHT (CANONICAL). Read-only factual check before any send. eligible_targets is the FINAL safe cohort: it already applies BOTH outreach-local safety and GLOBAL RECIPIENT SAFETY across every Outreach in the workspace, resolved by normalized email. You never need to call another endpoint or union blockers yourself. Per recipient, local_blockers and global_blockers are exposed for diagnostic transparency only. Global blocker codes: global_hard_bounce, global_unsubscribe, global_active_human_conversation, global_meaningful_reply_requires_individual_handling, global_duplicate_recent_send, global_existing_waiting_loop, global_suppression, global_identity_ambiguity. A hard bounce or unsubscribe recorded in ANY Outreach is workspace-level address evidence and blocks reuse elsewhere; an active human conversation discovered in another Outreach blocks generic campaign contact. Identity is never fuzzily merged: an ambiguous address is blocked, not merged. The response also reports autonomous_send_budget, which is INFORMATIONAL only — the budget is enforced transactionally when an execution is recorded. Forbiz never sends; this call changes nothing.

`GET /outreach/{id}/preflight`

## Request

- Base URL: `https://forbiz.io/api/public/agent`
- URL: `https://forbiz.io/api/public/agent/outreach/{id}/preflight`
- Auth: HTTP bearer

## Path parameters

- `id` string, required

## Query parameters

- `externalBatchId` string
- `externalSource` string
- `sendIntent` 'initial' | 'follow_up'
- `previousExecutionId` string
- `previousActionId` string
- `followUpStep` string

## Response `200`

Preflight

- object
  - `effective_state` string
  - `safe_to_send` boolean
  - `external_batch_already_recorded` boolean
  - `send_intent` 'initial' | 'follow_up'
  - `follow_up_grounding` object, nullable
  - `eligible_recipient_count` integer
  - `blocked_recipient_count` integer
  - `warning_recipient_count` integer
  - `blockers` string[]
  - `global_recipient_safety` object
    - `applied` boolean
    - `scope` string
    - `local_only_eligible_count` integer: How many recipients outreach-local safety alone would have allowed. Diagnostic.
    - `globally_blocked_count` integer
    - `additionally_blocked_by_global_safety` object[]
    - `blockers_by_code` object
  - `autonomous_send_budget` AutonomousSendBudget: Hard autonomous outbound budget. There is NO built-in default limit: if no policy is configured for the workspace/channel, autonomous sending is refused (configured=false). Enforcement is transactional at execution-recording time, under a row lock, outside model reasoning — preflight values are informational because another process may consume the remaining slots first.
    - `configured` boolean
    - `channel` string
    - `mode` 'autonomous' | 'manual'
    - `limit` integer, nullable
    - `used` integer
    - `remaining` integer, nullable
    - `window_start` string, nullable
    - `window_end` string, nullable
    - `timezone` string, nullable
    - `enforcement` string
  - `eligible_targets` object[]
  - `sendable_count` integer: Legacy alias of eligible_recipient_count.
  - `blocked_count` integer
  - `prevention` object
  - `sendable_targets` object[]
  - `blocked_targets` object[]

## Other responses

- `404`: Not found

---

[API](https://skmtc.dev/forbiz/apis/forbiz-external-agent-api.md) · [All operations](https://skmtc.dev/forbiz/apis/forbiz-external-agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/forbiz/apis/forbiz-external-agent-api/revisions/e5b10d59dc5f?raw)
