# POST /portals/data-sharing

**Resource:** [Portals](./portals.md)  
**MCP tool:** `set_portal_data_sharing`  
**Scopes:** `portals:write`  
**Write operation:** yes

Safely set ONE opportunity-auto-share rule (Container 1) on a portal instance OR a template — server-side merge, so you never replace the whole config. enabled=false fully protects the type; mode "all" auto-shares all of the anchored opportunity's records of that type, "selected" limits to resource_ids.

## Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `portal_id` | body | string | no | Target a live instance (one of portal_id/template_id). |
| `template_id` | body | string | no | Target a template (one of portal_id/template_id). |
| `content_type` | body | string | yes | One of: work_orders, transcripts, invoices, signing, documents, files, bookings, images, notepads. |
| `enabled` | body | boolean | no | Master switch. false = fully protected (never shared/seen). Defaults true when first set. |
| `mode` | body | string | no | "all" (auto-share every record) or "selected" (only resource_ids). |
| `resource_ids` | body | array | no | For mode "selected": the exact record ids. |
| `status_ids` | body | array | no | work_orders only: filter by status ids. |
| `member_can_edit` | body | boolean | no | work_orders/notepads: let members edit, not just view. |
| `member_editable_fields` | body | array | no | work_orders only, alongside member_can_edit: the field SLUGS a member may write. Status is always editable when member_can_edit is true, so this covers the data fields. Omit the key entirely for the original behaviour (every field editable); pass [] for status-only, so a contractor can accept or decline a job but cannot change the offer amount; pass null to clear the allowlist. |
| `member_selectable_statuses` | body | array | no | work_orders only: the status IDS a member may move a work order INTO — the status equivalent of member_editable_fields. Omit for the original behaviour (every workspace status offered); pass the short list a contractor should see instead of your internal quoting and payment stages; pass null to clear it. NOT the same as status_ids, which decides which work orders are shared into the portal at all. |
| `required_fields_by_status` | body | object | no | work_orders only: a completion gate, as {"<status id>": ["field_slug", …]}. Every listed slug must be filled before a member may move a work order INTO that status, enforced server-side — so a subcontractor cannot mark a job finished before the work is confirmed. Use the slug "_attachments" to require at least one photo. Pass {} or null to clear the gate. |
| `require_approval` | body | boolean | no | Optional. Set true to route this write into the approval queue for human review instead of executing it immediately (returns 202 + an approval_id). Works even when your key/token has permission to execute directly. |

## Request example

```bash
curl -X POST   "https://api.trustpager.com/functions/v1/api/v1/portals/data-sharing"   -H "Authorization: Bearer YOUR_API_KEY"   -H "Content-Type: application/json"   -d '{"portal_id":"...","template_id":"...","content_type":"..."}'
```

---
Base URL: `https://api.trustpager.com/functions/v1/api/v1` — Auth: `Authorization: Bearer YOUR_API_KEY`