Projects
Environment-scoped grouping inside a workspace.
A project is the granular unit under a workspace. Use one project per
environment (Production, Staging, Development) or per product surface
(Transactional, Marketing), whichever maps to how you reason about
sending volume and isolation.
Each project carries its own:
- API keys: a key issued in
Stagingcannot send throughProduction. - Templates: versioned and scoped to the project.
- Send history: analytics dashboards filter by project.
Workspace-level objects (providers, billing, members) are shared across all projects so you don't re-key SendGrid five times.
Creating projects
A default Production project is created with every workspace. Create more
through the dashboard or the Management API:
curl https://app.dev.messagepipe.dev/api/projects \
-H "Cookie: mp_session=..." \
-H "Content-Type: application/json" \
-d '{ "workspace_id": "wks_…", "name": "Staging", "environment": "staging" }'Default sender and sender domains
Each project can carry a default sender (default_from_email,
default_from_name, default_reply_to), used by an email send that names no
sender of its own.
A send may name its own sender with from, but only on one of the
project's sender domains: the default sender's domain, plus any
listed in sender_domains. Anything else is refused with
403 sender_not_allowed. Add a domain with:
curl -X PATCH https://app.dev.messagepipe.dev/api/projects/prj_… \
-H "Cookie: mp_session=..." \
-H "Content-Type: application/json" \
-d '{ "sender_domains": ["example.com", "mail.example.com"] }'Domains are bare names, matched exactly (a subdomain needs its own entry), up
to 20 per project. An empty array clears the list. A project with no default
sender and no sender_domains doesn't restrict from at all.
The list is checked when a send is accepted, so sends already queued or
scheduled keep the from they were accepted with after you remove a domain.
Changes to sender_domains are recorded in the audit log as
project.sender_domains_updated, with the previous and new lists.
MessagePipe only checks the list; the domain still has to be verified with your
email provider (SPF and DKIM) for mail to authenticate.
Pinning providers to a project
By default a project routes across every active provider in the workspace (see Providers). Pin one or more providers to a project to control which of them its sends can use. The pins apply to everything sent with the project's API keys and templates.
curl -X PATCH https://app.dev.messagepipe.dev/api/projects/prj_… \
-H "Cookie: mp_session=..." \
-H "Content-Type: application/json" \
-d '{ "provider_pins": ["prv_…", "prv_…"], "provider_pins_exclusive": true }'provider_pins lists provider configuration ids (up to 20). Each must be a provider the project
can use: workspace-wide, or attached to this project. A provider attached to another project is
refused. An empty array removes the pins and the project goes back to routing across every provider
it can reach.
provider_pins_exclusive decides what the list means, and defaults to true:
| Mode | Behaviour |
|---|---|
Exclusive (true) | Only the pinned providers can take a send. A preferred_provider or providers list on the request that names anything else is not honoured. If none of the pinned providers can take the send, it fails with failure_code: provider_not_pinned. It is never routed outside the list, and credits already taken for it are refunded. |
Preferred (false) | The pinned providers are tried first, in the usual priority, health and weight order. The workspace's other providers stay available as a fallback. A request's own providers list is left as the caller wrote it. |
Within the pinned set the normal routing rules still
apply: inactive providers and providers that are down are skipped, and a retryable
failure moves on to the next pinned provider. When a provider is pinned and the request
asks for its type ("preferred_provider": "sendgrid"), the pinned configuration of that
type is the one used.
A pin is checked when the send is dispatched, so a change takes effect for sends that are
still queued or scheduled. If a pinned provider is deleted, its pin stays in the list and
an exclusive project stays restricted (its sends fail) until you update the list; deleting
a provider never silently opens a project up to the rest of the workspace. Changes to
the pins are recorded in the audit log as project.provider_pins_updated, with the
previous and new settings.