MOLTED EMAIL

Contacts & Accounts

Sync contacts, manage accounts, and maintain your contact data through the API.

Contacts represent the people you email. Each contact belongs to a tenant and can optionally be associated with an account (company).

Sync contacts

Bulk upsert contacts into your tenant. Existing contacts are matched by email and updated; new contacts are created.

POST https://api.molted.email/v1/contacts/sync
curl
curl -X POST https://api.molted.email/v1/contacts/sync \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "contacts": [
      {
        "email": "jane@acme.com",
        "name": "Jane Smith",
        "ownerEmail": "rep@yourco.com",
        "lifecycleStage": "customer",
        "dealStage": "closed_won",
        "accountId": "acc_123",
        "metadata": { "plan": "enterprise", "region": "us-west" }
      }
    ]
  }'

List contacts

molted contacts list

Filter by email:

molted contacts list --email jane@acme.com
FlagTypeRequiredDescription
--emailstringNoFilter by exact email address.
GET https://api.molted.email/v1/contacts
curl
curl "https://api.molted.email/v1/contacts?tenantId=tenant_abc123&email=jane@acme.com" \
  -H "Authorization: Bearer YOUR_API_KEY"
ParameterTypeRequiredDescription
tenantIdstringYesYour tenant identifier.
emailstringNoFilter by exact email address.

Response

Returns an array of contact objects. Returns up to 100 contacts, ordered by most recently updated.

Response
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "jane@acme.com",
    "name": "Jane Smith",
    "ownerEmail": "rep@yourco.com",
    "lifecycleStage": "customer",
    "dealStage": "closed_won",
    "accountId": "acc_123",
    "externalId": null,
    "metadata": { "plan": "enterprise", "region": "us-west" },
    "createdAt": "2026-03-01T12:00:00Z",
    "updatedAt": "2026-03-01T12:00:00Z"
  }
]

If you have no contacts yet, the response is an empty array:

Empty response
[]

No contacts yet? Contacts are created automatically when you send your first email. You can also bulk-import contacts with molted contacts sync. See syncing contacts above.

Get contact by ID

GET https://api.molted.email/v1/contacts/:id
curl
curl https://api.molted.email/v1/contacts/CONTACT_ID \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

Response
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "jane@acme.com",
  "name": "Jane Smith",
  "ownerEmail": "rep@yourco.com",
  "lifecycleStage": "customer",
  "dealStage": "closed_won",
  "accountId": "acc_123",
  "externalId": null,
  "metadata": { "plan": "enterprise", "region": "us-west" },
  "createdAt": "2026-03-01T12:00:00Z",
  "updatedAt": "2026-03-01T12:00:00Z"
}

Contact model

FieldTypeDescription
idstringUnique contact identifier.
emailstringContact's email address.
namestringDisplay name.
ownerEmailstringEmail of the assigned owner (e.g., sales rep).
lifecycleStagestringCurrent lifecycle stage (e.g., lead, customer).
dealStagestringCurrent deal stage (e.g., qualified, closed_won).
accountIdstringAssociated account identifier.
externalIdstringExternal CRM identifier (e.g., HubSpot or Salesforce ID).
metadataobjectArbitrary key-value pairs for custom data.
createdAtstringISO-8601 timestamp when the contact was created.
updatedAtstringISO-8601 timestamp when the contact was last updated.

Create a contact

Create a single contact explicitly. The email must be unique within your tenant — a duplicate returns 409 Conflict. (For bulk upserts that tolerate duplicates, use sync.)

molted contacts create --email jane@acme.com --name "Jane Smith" \
  --metadata '{"plan":"enterprise"}'
FlagTypeRequiredDescription
--emailstringYesContact email address.
--namestringNoDisplay name.
--owner-emailstringNoAssigned owner email.
--lifecycle-stagestringNoLifecycle stage.
--deal-stagestringNoDeal stage.
--external-idstringNoExternal CRM identifier.
--metadatastringNoMetadata as a JSON object.
POST https://api.molted.email/v1/contacts
curl
curl -X POST https://api.molted.email/v1/contacts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "email": "jane@acme.com",
    "name": "Jane Smith",
    "metadata": { "plan": "enterprise" }
  }'

Returns the created contact object (201 Created).

Update a contact

Update fields on an existing contact by ID. metadata is merged at the top level — supplied keys overwrite existing ones, other keys are preserved.

molted contacts update CONTACT_ID --name "Jane S." --metadata '{"plan":"pro"}'
PATCH https://api.molted.email/v1/contacts/:id
curl
curl -X PATCH https://api.molted.email/v1/contacts/CONTACT_ID \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "name": "Jane S.",
    "metadata": { "plan": "pro" }
  }'

Returns the updated contact object, or 404 Not Found if the contact does not exist.

You can also update by email with sync, which upserts and merges existing contacts.

Delete a contact

Permanently delete a contact (GDPR right-to-erasure). This removes the contact and also removes it from any lists (decrementing subscriber counts) and segments. This cannot be undone.

molted contacts delete CONTACT_ID
DELETE https://api.molted.email/v1/contacts/:id
curl
curl -X DELETE "https://api.molted.email/v1/contacts/CONTACT_ID?tenantId=tenant_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"

Returns { "deleted": true }, or 404 Not Found if the contact does not exist.

Accounts

Accounts represent companies or organizations. Contacts can be linked to an account via the accountId field. Accounts are created automatically when contacts are synced with an account association, or can be managed through your CRM integration.