sender-profile-architect — Claude Code skill: setup & design guide
Designs Sent v3 Sender Profile architecture for multi-tenant and multi-channel applications. It helps set up isolation, API key scoping, WABA, and billing boundaries.
npx skills add sentdm/sent-plugin --skill sender-profile-architect -a claude-codeWhat sender-profile-architect does
This skill plans operational boundaries in Sent v3 before provisioning begins. It defines tenant isolation boundaries. The skill outlines whether contacts and TCR templates are inherited or shared, and structures payloads for POST /v3/profiles. Live MCP actions belong in sent-profile-provisioning, leaving this skill focused on structural architecture.
Sent v3 separates credential boundaries strictly. An organization API key can act for a child profile via the x-profile-id header while drawing from the shared organization rate limit. Conversely, a profile-specific API key isolates credentials and limits: sending x-profile-id with it causes a 403 error. The legacy x-sender-id header is rejected.
Webhook events omit internal tenant identifiers. Because of that, you must store and map the returned message_id and inbound phone numbers to your tenant IDs locally. Inferring ownership from account_id alone fails because multiple tenant profiles live under one organization.
What it helps with
- Map tenant boundaries and communication channels
- Scope API credentials between organization and profile keys
- Select WABA integration paths for tenants
- Design webhook attribution using
message_id
Example prompts for the agent
- Design a multi-tenant Sender Profile model for Sent v3 with separate billing contacts.
- Help me configure 10DLC campaign inheritance and contact sharing flags.
- Show how to route Sent webhook events back to our application tenant records.
How to install sender-profile-architect
1Skills CLI (Vercel)
npx skills add sentdm/sent-plugin --skill sender-profile-architect -a claude-code2Manually: put the files in place
~/.claude/skills/sender-profile-architect/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/sender-profile-architect/
1Skills CLI (Vercel)
npx skills add sentdm/sent-plugin --skill sender-profile-architect -a codex2Manually: put the files in place
.agents/skills/sender-profile-architect/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add sentdm/sent-plugin --skill sender-profile-architect -a cursor2Manually: put the files in place
.cursor/skills/sender-profile-architect/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install sentdm/sent-plugin sender-profile-architect2Manually: put the files in place
.github/skills/sender-profile-architect/SKILL.md1Skills CLI (Vercel)
npx skills add sentdm/sent-plugin --skill sender-profile-architect -a gemini-cli2Platform CLI
gemini skills install https://github.com/sentdm/sent-plugin --path skills/sender-profile-architectManually: put the files in place
.devin/skills/sender-profile-architect/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add sentdm/sent-plugin --skill sender-profile-architect -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about sender-profile-architect
How to install sender-profile-architect in Claude Code?
Run npx skills add sentdm/sent-plugin --skill sender-profile-architect -a claude-code.
What does sender-profile-architect do?
It guides the architectural design of Sent v3 profiles, credentials, inheritance rules, and channel resources before you provision them.
When should you use an organization key instead of a profile key?
Use an organization key with x-profile-id for centrally managed integrations that share a rate-limit pool. Profile keys are required when tenant credentials must remain strictly isolated.
Source text
SKILL.md · MIT
---
name: sender-profile-architect
description: Designs Sent Sender Profile architecture for multi-tenant, multi-brand, and multi-channel systems. Use for API-key scoping, x-profile-id, isolation, inheritance, sharing, billing, WABA, 10DLC campaigns, webhooks, or tenant offboarding.
---
# Sender Profile Architect
A Sender Profile is the operational boundary for tenant identity, channel configuration, inherited resources, billing, and credentials. Use this skill before provisioning when a poor boundary would mix brands, compliance posture, rate-limit impact, or webhook ownership.
For live MCP profile lifecycle operations use `sent-profile-provisioning`; for market requirements use `sent-compliance`. MCP selects an acting profile with optional `profileId` on ordinary account tools for organization grants only. `sender_profiles.*` tools operate on target `id` and reject acting `profileId`. REST headers below are not MCP arguments.
## Recommended tenancy model
When tenants require isolation, recommend one Sent organization with one Sender Profile per tenant. A shared profile is appropriate only when the tenants genuinely share one brand, sender resources, compliance posture, billing/rate-limit expectations, and operational blast radius.
Do not recommend pooled-by-default architecture. Make the isolation decision explicit using [references/multi-tenancy-patterns.md](references/multi-tenancy-patterns.md).
## Authentication patterns
Sent v3 supports both:
| Pattern | Headers | Blast radius |
| --- | --- | --- |
| Profile-specific API key | `x-api-key` | Profile-scoped credentials and rate-limit context. Do not add `x-profile-id`. |
| Organization API key acting for a child | `x-api-key` plus `x-profile-id: <profile UUID>` | Organization credential can reach permitted child profiles; rate limits remain in the organization pool. |
Only organization keys may send `x-profile-id`. A profile key that sends it receives `403`. A profile outside the organization returns `404`. `X-Profile-Id` can be echoed in scoped responses.
`x-sender-id` is legacy v1/v2 terminology only. Do not use it for v3 authentication or routing.
Choose profile keys when tenant-level credential isolation and revocation are primary. Choose organization-key scoping for centrally controlled integrations that can protect a broader credential and deliberately accept a shared organization rate-limit pool.
## Profile creation model
Create with `POST /v3/profiles`. `name` is required. Current optional areas include:
- identity: `icon`, `description`, `short_name`;
- sharing: `allow_contact_sharing`, `allow_template_sharing`;
- inheritance: `inherit_contacts`, `inherit_templates`, `inherit_tcr_brand`, `inherit_tcr_campaign`;
- billing: `billing_model`, `billing_contact`, and ephemeral `payment_details`;
- dedicated WABA credentials: `whatsapp_business_account` with `waba_id`, optional `phone_number_id`, and `access_token`;
- a dedicated brand: `brand.contact`, `brand.business`, and `brand.compliance`.
Do not add a separate brand endpoint. A dedicated brand is created with the profile; campaigns are managed under `/v3/profiles/{profileId}/campaigns`.
### Inheritance rules
- `inherit_tcr_brand: true` means the profile uses the organization's brand and cannot submit its own `brand` object.
- `inherit_tcr_campaign: true` makes inherited campaigns read-only for that profile.
- An inherited brand with `inherit_tcr_campaign: false` is a supported dedicated-campaign pattern.
- Sharing flags expose a profile's contacts/templates; inheritance flags consume organization resources. Treat those directions separately.
### Billing and number references
`billing_model` currently supports `profile`, `organization`, and `profile_and_organization`. A profile or fallback billing model requires `billing_contact` when none exists. Card fields are forwarded to the payment processor and must not be logged or persisted.
Profile update can manage `sending_phone_number_profile_id`, `sending_whatsapp_number_profile_id`, `sending_phone_number`, `whatsapp_phone_number`, and `allow_number_change_during_onboarding`. Model reference IDs and direct numbers separately, and prevent cycles when one profile references another.
## WABA choices
There are three distinct paths:
1. Organization Embedded Signup in the dashboard.
2. Child profile inheritance by omitting `whatsapp_business_account` after the organization has a WABA.
3. Dedicated profile WABA using `waba_id` and `access_token`; `phone_number_id` is optional.
There is no public endpoint that starts organization Embedded Signup. Direct credentials on `POST /v3/profiles` are not an “Embedded Signup endpoint.” Use `waba-embedded-signup` for the operational flow.
## 10DLC and campaigns
Use a profile `brand` object for a dedicated brand. Manage campaigns at:
- `GET|POST /v3/profiles/{profileId}/campaigns`
- `PUT|DELETE /v3/profiles/{profileId}/campaigns/{campaignId}`
Use `sms-10dlc-registration` for the payload and policy layer.
## Completion and status handling
Complete a profile with `POST /v3/profiles/{profileId}/complete` and a required `webHookUrl`:
```json
{
"webHookUrl": "https://example.com/webhooks/profile-complete",
"sandbox": true
}
```
Status is surface-specific:
- Create response currently demonstrates lowercase `incomplete`.
- Completion `202` means processing started and does not contain a final status.
- Completion `200` currently demonstrates lowercase `completed` for an already-complete profile.
- Completion callbacks can report `COMPLETED`, `SUBMITTED`, or `failed`.
- REST guides and OpenAPI publish different profile status sets.
Do not assert a closed REST enum. Preserve unknown strings and record the endpoint/callback surface that produced them.
## Webhook attribution
Sent events do not contain your application tenant ID. Before sending, persist the returned `message_id` with the tenant and profile. Route outbound status events through that mapping. For inbound messages, map the receiving number/profile resource to the tenant.
```text
message_id -> tenant_id, profile_id, logical_send_id, channel
receiving_number -> tenant_id, profile_id
```
Do not infer tenant ownership from `account_id` alone. Multiple tenant profiles can belong to one organization.
## Design checklist
- [ ] Tenant/brand isolation decision is explicit.
- [ ] Credential pattern and rate-limit/blast radius are documented.
- [ ] Sharing and inheritance directions are intentional.
- [ ] Billing ownership is named.
- [ ] Number references cannot form cycles.
- [ ] WABA path is organization signup, inheritance, or dedicated credentials—not an invented hybrid.
- [ ] Dedicated brand/campaign paths are profile-based.
- [ ] `message_id` and inbound-number mappings support webhook attribution.
- [ ] Unknown profile statuses are tolerated.
- [ ] Tenant offboarding revokes credentials, disables sends, detaches resources safely, and retains audit evidence.
See [references/sender-profile-data-model.md](references/sender-profile-data-model.md) and [references/profile-boundary-examples.md](references/profile-boundary-examples.md) for implementation patterns.
© sentdm · MIT · sentdm/sent-plugin