> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clawb.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Email sending enforcement

Clawb can act as a **backend enforcement point** for email sending:

1. Your service calls `POST /v1/check` with `action: "send_email"` and an `email` object (recipients, attachment metadata, etc.)
2. If Clawb returns `allow`, your service calls `POST /v1/email/send` to send the email **server-side via SendGrid**
3. If Clawb returns `deny` or `challenge`, your service must **not** send the email

<Info>
  **Auth quick reference**

  <CodeGroup>
    ```http HTTP theme={null}
    # Preferred
    X-Clawb-Api-Key: ck_live_9f2b3c4d5e6f7a8b

    # Alternative
    Authorization: Bearer ck_live_9f2b3c4d5e6f7a8b
    ```
  </CodeGroup>

  Use provider keys with the `ck_live_` or `ck_test_` prefix.
</Info>

## Step 1 — Ask for a decision

<CodeGroup>
  ```bash curl theme={null}
  curl -sS -X POST "https://api.clawb.ai/api/v1/check" \
    -H "Content-Type: application/json" \
    -H "X-Clawb-Api-Key: ck_live_9f2b3c4d5e6f7a8b" \
    -d '{
      "agent_id": "agt_...",
      "policy_id": "pol_email",
      "action": "send_email",
      "email": {
        "to": ["user@example.com"],
        "subject": "Your receipt",
        "attachments": []
      }
    }'
  ```

  ```python Python SDK theme={null}
  from clawb_agent_sdk import ClawbClient, WorkspaceControlPlane

  client = ClawbClient(base_url="https://api.clawb.ai/api")
  control_plane = WorkspaceControlPlane(client=client, api_key="ck_live_9f2b3c4d5e6f7a8b")

  decision = control_plane.check(
      agent_id="agt_...",
      policy_id="pol_email",
      action="send_email",
      email={
          "to": ["user@example.com"],
          "subject": "Your receipt",
          "attachments": [],
      },
  )
  print(decision)
  ```
</CodeGroup>

## Step 2 — Send (only if allowed)

`/v1/email/send` requires a workspace API key header.

<CodeGroup>
  ```bash curl theme={null}
  curl -sS -X POST "https://api.clawb.ai/api/v1/email/send" \
    -H "Content-Type: application/json" \
    -H "X-Clawb-Api-Key: ck_live_9f2b3c4d5e6f7a8b" \
    -d '{
      "agent_id": "agt_...",
      "policy_id": "pol_email",
      "email": {
        "to": ["user@example.com"],
        "subject": "Your receipt",
        "text": "Thanks for your purchase!",
        "html": "<p>Thanks for your purchase!</p>"
      }
    }'
  ```

  ```python Python SDK theme={null}
  from clawb_agent_sdk import ClawbClient

  client = ClawbClient(base_url="https://api.clawb.ai/api")

  send_out = client.post(
      "/v1/email/send",
      headers={"X-Clawb-Api-Key": "ck_live_9f2b3c4d5e6f7a8b"},
      json={
          "agent_id": "agt_...",
          "policy_id": "pol_email",
          "email": {
              "to": ["user@example.com"],
              "subject": "Your receipt",
              "text": "Thanks for your purchase!",
              "html": "<p>Thanks for your purchase!</p>",
          },
      },
  )
  print(send_out)
  ```
</CodeGroup>

### Response

<CodeGroup>
  ```json JSON theme={null}
  {
    "ok": true,
    "provider": "sendgrid",
    "provider_message_id": "..."
  }
  ```
</CodeGroup>

### Blocked sends

If policy evaluation denies or challenges, `/v1/email/send` returns **403** with a stable payload:

<CodeGroup>
  ```json JSON theme={null}
  {
    "error": "policy_blocked",
    "decision": "deny" | "challenge",
    "reasons": ["..."],
    "challenge": {"type": "...", "url": "..."}
  }
  ```
</CodeGroup>
