CoreSwift CRM

Customer Relationship Management Platform
v0.1.0 · API /api/

Welcome to CoreSwift CRM

A modern, multi-tenant Customer Relationship Management platform built to manage contacts, companies, sales pipelines, opportunities, tags, lists, and webhook integrations all in one place.

1 Getting Started

Login to CoreSwift CRM

Navigate to:

https://coreswiftcrm.com

Enter your email and password.

Demo Account Ask the operator for a demo sign-in — the password is rotated (see the admin guide).

On success, you receive a JWT access token and refresh token. The app stores these for all API calls. You'll be redirected to the Dashboard.

Navigation

??
Dashboard
Stats and activity
??
Contacts
People management
??
Companies
Organizations
??
Pipelines
Sales stages
??
Opportunities
Deals & values
???
Tags
Labels & categories
??
Lists
Saved contact groups
??
Webhooks
API integrations
??
Settings
Account & API keys

API Overview

All endpoints sit under /api/:

  • Public: auth/login, auth/register, auth/forgot-password, auth/reset-password
  • Protected: All others require Authorization: Bearer <token>

2 Dashboard

Stats Cards

At-a-glance CRM metrics for your own account, fetched via GET /api/dashboard/stats. Every counter is scoped to the account in the token.

??
Total Contacts
??
Companies
??
Opportunities
?
$
Won Deal Value
GET /api/dashboard/stats
Authorization: Bearer <token>

Response:
{
  "total_contacts": 42,
  "total_companies": 15,
  "total_opportunities": 28,
  "total_revenue": 5000.00
}

total_contacts, total_companies and total_opportunities are row counts for your account. total_revenue is money, not a count: it is the sum of opportunities.value over the opportunities you have marked won, and 0 when you have none. These four are the whole response — no other key is returned.

Pipeline Summary

Below the stats cards, each active pipeline shows opportunity counts per stage, giving a visual funnel of where deals are concentrated. Default pipelines are highlighted.

Global Search

Search all entities at once:

GET /api/dashboard/search/query?q=david

Matches across contacts (first name, last name, full name, email, phone), companies (name/email), and opportunities (name). Returns top 10 per type, and only from your own account.

GET /api/dashboard/search/query?q=david
Authorization: Bearer ***

Response:
{
  "query": "david",
  "total_contacts": 42,
  "total_companies": 15,
  "contacts": [
    { "id": "1f0c...", "first_name": "David", "last_name": "Giraudy", "email": "david@example.com", "phone": "+13055550100" }
  ],
  "companies": [
    { "id": "9a24...", "name": "Acme Corp", "email": "info@acme.example" }
  ],
  "opportunities": [
    { "id": "77c1...", "name": "David renewal", "value": 12000.00, "is_won": false }
  ]
}

total_contacts and total_companies are your own row totals — the same numbers as GET /api/dashboard/stats — and not the number of matches; the matches are the three arrays. A request with no q (or a blank one) returns those totals with three empty arrays, and so does a query that matches nothing.

3 Contacts

Contact Fields

FieldTypeDescription
first_nameStringRequired
last_nameStringRequired
emailString (opt)Email address
phoneString (opt)Phone number
companyString (opt)Free-text company
job_titleString (opt)Job title
city/state/countryString (opt)Location
sourceString (opt)Acquisition source
scoreIntegerAuto-calculated lead score
metadataJSON (opt)Custom data

Adding a Contact

Navigate to Contacts

Click Contacts in the sidebar.

Click "Add Contact"

A form modal opens.

Fill in details

First / last name required. Email or phone recommended.

Save

Click Save in the dialog.

POST /api/contacts
Authorization: Bearer <token>
Content-Type: application/json

{
  "first_name": "John",
  "last_name": "Doe",
  "email": "john@example.com",
  "phone": "+1234567890",
  "company": "Acme Corp",
  "source": "Website"
}

Edit, Delete & Search

  • Edit The row's Edit button → PATCH /api/contacts/:id
  • Delete Soft delete by API only (DELETE /api/contacts/:id) — a contact row has no delete control
  • View / edit Every row carries an Edit and a Tags button; there is no contact detail page
  • Search GET /api/contacts/search?q=john (name/email/phone)

Assigning Tags

Open the tag panel

Click Tags on the contact's row.

Current tags

Existing tags are shown as colored pills, each with an ✕ to unassign.

Assign a tag

Pick one of the remaining tags listed below the pills.

Confirm

Uses POST /api/tags/assign. Remove via DELETE /api/tags/assign/:id.

Lead Scoring

Score rules fire automatically:

RulePointsDirection
Email Opened+5Add
Email Clicked+15Add
Email Replied+25Add
Booked a Call+50Add
Proposal Requested+75Add
No Activity 30 Days-20Subtract
Unsubscribed-100Subtract

Finding Duplicate Contacts

Over time the same person can end up in your workspace more than once — imported from a spreadsheet on Monday, added by hand on Friday. The Duplicates screen (in the sidebar, directly under Contacts) shows you every set of records that look like the same person so you can decide what to keep.

It compares two things:

  • The same phone number, once punctuation and spacing are ignored — (561) 555-0143 and 5615550143 count as the same number.
  • The same first and last name, once case and extra spaces are ignored.

Email addresses are deliberately not compared: a workspace can never hold two active contacts with the same email address, so a report on email could only ever come back empty.

Nothing is merged automatically. Each row has an Edit button that opens that contact in the normal editor, so you decide which record survives and what it says. If a group names a record you cannot see in the list above it, the record is still there — the name lookup stops after 500 contacts, and the screen says so rather than pretending the contact is missing.

If you see "Account matching is not available on your current plan", the report is switched on for paid plans only. The screen tells you that instead of showing an empty list, because "you have no duplicates" and "you are not allowed to look" are different answers.

GET /api/account-match/duplicates?limit=25
Authorization: Bearer ***

{
  "groups": [
    { "kind": "phone", "key": "5615550143", "count": 2,
      "contact_ids": ["6b5f8ccc-…", "cd67aebd-…"] }
  ],
  "total_groups": 1,
  "contacts_in_groups": 2
}

4 Companies

Company Fields

FieldTypeDescription
nameStringRequired
websiteString (opt)Company URL
phoneString (opt)Main phone
emailString (opt)Contact email
industryString (opt)e.g. Technology, Healthcare
sizeString (opt)1-10, 11-50, 51-200, 201-1000, 1000+
city/state/countryString (opt)HQ location
descriptionText (opt)Free text

Managing Companies

Go to Companies

Companies has no sidebar entry — press g then o to open it.

Add a Company

Name required. Optionally set industry/size.

POST /api/companies
Content-Type: application/json

{ "name": "Acme Corp", "industry": "Technology", "size": "51-200" }
Link Contacts

Companies have no detail page; a contact carries a free-text company field and the Companies list shows a per-company contact count.

Edit or Delete

Soft delete (is_active = false).

Companies & Opportunities

Link a company to an opportunity via company_id to track all deals per organization.

Tip: Use industry and size for segmentation and reporting.

5 Pipelines

Understanding Pipelines

A Pipeline is a sales process composed of sequential Stages. Opportunities move through these stages toward close.

Default Pipelines: Every new tenant gets Sales Pipeline (7 stages) and Client Onboarding (5 stages).

Sales Pipeline Stages

StageColorOrderProbability
New LeadGray05%
ContactedBlue110%
QualifiedPurple225%
Appointment SetAmber340%
Proposal SentGreen460%
WonDark Green5100%
LostRed60%

Client Onboarding Stages

StageColorOrderProbability
New ClientGray010%
Documents ReceivedBlue125%
Setup In ProgressPurple250%
ActiveGreen3100%
RetentionDark Green4100%

Creating a Pipeline

Go to Pipelines

Click Pipelines & Deals under Sales in the sidebar.

Click "New Pipeline"

Enter a name and optional description.

Add Stages

Each stage needs name, color, sort order and probability.

Save

The pipeline appears on the Pipelines & Deals screen and counts towards the dashboard Pipelines tile.

POST /api/pipelines
Authorization: Bearer <token>

{ "name": "Support Pipeline", "description": "Support lifecycle", "is_default": false }

Stage Configuration

Each stage supports:

  • Name Display label
  • Color Hex color (e.g. #3B82F6)
  • Sort Order Integer position
  • Probability Win % (0-100)
  • is_won Mark as closed-won stage
  • is_lost Mark as closed-lost stage

6 Opportunities

What is an Opportunity?

An Opportunity (deal/tracker) represents a potential sale or business outcome progressing through a pipeline. Each opportunity is tied to a specific pipeline and stage.

FieldTypeDescription
nameStringRequired. Deal name
pipeline_idUUIDRequired. Which pipeline it belongs to
stage_idUUIDRequired. Current stage within the pipeline
valueFloat (opt)Deal value / amount
currencyString (opt)e.g. USD, EUR
probabilityInteger (opt)Override win probability
expected_close_dateDate (opt)Expected close date
contact_idUUID (opt)Associated contact
company_idUUID (opt)Associated company
sourceString (opt)e.g. Website, Referral
notesText (opt)Internal notes
is_wonBooleanMarked as won
is_lostBooleanMarked as lost
lost_reasonString (opt)Why the deal was lost

Creating an Opportunity

Go to the Pipeline

Open the pipeline where you want to add a deal.

Click "+ Deal"

The New Deal dialog opens.

Set deal details

Name is required. Set value, stage, expected close date. Optionally link a contact and/or company.

Save

The opportunity appears in the correct stage column.

POST /api/pipelines/:pipeline_id/opportunities
Authorization: Bearer ***

{
  "stage_id": "uuid-of-stage",
  "name": "Enterprise Deal - Acme Corp",
  "value": 50000.0,
  "currency": "USD",
  "probability": 60,
  "expected_close_date": "2026-08-15",
  "contact_id": "uuid-of-contact",
  "company_id": "uuid-of-company",
  "source": "Referral",
  "notes": "Initial call went well"
}

Moving Deals Through the Pipeline

To advance an opportunity to the next stage:

  • Drag-and-drop Drag an opportunity card from one stage column to another
  • Change stage dropdown Use the stage selector on the deal card in its stage column

Both actions use:

PATCH /api/pipelines/:pipeline_id/stages/:stage_id/move/:opportunity_id
Authorization: Bearer ***

{ "stage_id": "uuid-of-next-stage" }

Value, probability, expected close date and notes are updated with PATCH /api/pipelines/:pipeline_id/opportunities/:id.

Winning & Losing Deals

When a deal reaches a Won or Lost stage, CoreSwift automatically sets the corresponding boolean flags:

  • Won: is_won = true adds value to the "Won Deal Value" dashboard stat
  • Lost: is_lost = true optionally record a lost_reason for analysis
Tip: Track lost reasons to analyze patterns and improve your sales process.

Opportunity Analytics

The dashboard carries three of these tiles, each read from GET /api/dashboard/stats:

  • Opportunities Opportunity count for the account
  • Won Deal Value Won opportunity value
  • Pipelines Number of pipelines

Per-stage counts are not shown anywhere.

7 Sales

Sales Group Overview

The sidebar's Sales group holds one screen, Pipelines & Deals (each pipeline's cards are its deals/opportunities). Contacts is a top-level sidebar item of its own, and Companies has no sidebar entry — open it with g then o. The group is collapsed by default — click Sales to expand it.

Tip: Accordion menus keep your sidebar clean. Collapse groups you don't frequently use.

Contacts

Contact management with search (/api/contacts, GET /api/contacts/search), pagination (50 rows per page by default) and add/edit dialogs. A contact has no status field and the list has no status column.

GET /api/contacts
POST /api/contacts
PATCH /api/contacts/:id

Companies

Track organizations with name, domain, industry, and contact count. Searchable and paginated.

GET /api/companies
POST /api/companies
PATCH /api/companies/:id

Pipelines & Deals

Manage sales pipelines with custom stages. Track deals through pipeline stages with value, probability, and stage tracking.

GET /api/pipelines
POST /api/pipelines
GET /api/pipelines/:pipeline_id/opportunities
POST /api/pipelines/:pipeline_id/opportunities

8 Marketing

Marketing Group Overview

Contains Campaigns, Lists and Analytics. Expand it by clicking Marketing in the sidebar.

Campaigns

Create and manage marketing campaigns. Each campaign has a type (email, SMS, multi-channel), status (draft/active), and sent count. Activate campaigns from the list view.

GET /api/campaigns
POST /api/campaigns
PATCH /api/campaigns/:id
POST /api/campaigns/:id/activate
POST /api/campaigns/:id/pause

Email Sequences

Build automated email sequences with multiple steps. Each sequence can have triggers, enrollments, and step-based delays. There is no separate Email Sequences screen — sequences are campaign records, managed under Marketing > Campaigns.

GET /api/campaigns
GET /api/campaigns/:id               (includes steps)
GET /api/campaigns/:id/enrollments   (view enrolled contacts)

Automation Rules

Create trigger-based automation rules. Configure triggers (tag added, score changes, list membership changes) and actions (add/remove tag, move stage, add/remove from list). Each rule has a trigger config and action config stored as JSON.

Available triggers: tag_added, score_change, list_added, deal_stage

Available actions: add_tag, remove_tag, move_stage, add_to_list, remove_from_list

GET /api/automation/rules
POST /api/automation/rules
PATCH /api/automation/rules/:id
DELETE /api/automation/rules/:id
Trigger Config Example: {"tag_id": "uuid"} for tag-based triggers, {"category": "overall", "min_score": 70} for score-based.

Checklists

Define checklist templates with stages for onboarding and process management. Each stage has an order, title, optional message template reference, and delay in hours. View instances and track progress.

GET /api/checklists/templates
POST /api/checklists/templates
PATCH /api/checklists/templates/:id
DELETE /api/checklists/templates/:id
GET /api/checklists/instances

9 Events, Portfolio & Lists

Where these live

There is no Operations group in the sidebar. The recorded event feed is API-only; portfolio companies are managed in the platform console under Portfolio Companies; lists live under Marketing > Lists.

Events

Logged system events — each with its type, description, related entity and date — are read through the API. There is no Events screen in the console.

GET /api/events

Portfolio

View all portfolio companies across your user ecosystem. Searchable by name, slug, or domain. Shows status, plan assignment, and active/inactive state.

GET /api/portfolio

Your company’s login

If the CoreSwift team set your company up, your workspace and your owner login were created together, and the login details were emailed to the address on the company record. Sign in with that password, then change it in Settings → Change password. If no email arrived, use Forgot password? on the sign-in page — that sends a fresh link to the same address.

Call Records

Telnyx call records — caller, called number, duration, disposition, cost and timestamp — are stored for billing and audit. There is no Call Logs screen in the CRM and no endpoint that lists them, so they are not shown in the app today.

Lists

Create and manage contact lists. Each list shows member count and can be used for campaign targeting. View members inline from the list detail.

GET /api/lists
POST /api/lists
PATCH /api/lists/:id
DELETE /api/lists/:id
GET /api/lists/:id/members
POST /api/lists/:id/members

🆘 Customer Support Portal

Your Help Desk — Built In

CoreSwift CRM includes a complete customer support ticketing system. Replace Freshdesk, Zendesk, or your overloaded email inbox. Your customers submit requests. Your team manages them. Nothing leaves the platform.

No API keys. No chatbot plugins. No external subscriptions. It just works.

How Tickets Come In

Tickets can arrive through multiple channels — all tracked by source so you know where every request came from:

ChannelSource CodeHow
👤 ManualmanualYour team creates tickets in the admin Support panel
🌐 Contact FormformDrop our embed widget on any website — visitors submit tickets without logging in. Anyone who writes from the contact page is handed a reference, and can come back to that page with the reference and their email address to read your team's answer — no sign-in needed.
📧 EmailemailForward your support@ inbox to our parser — emails become tickets automatically
🤖 ChatbotagentConnect any chatbot or AI agent via our public API — tickets created programmatically

None of these channels is privileged. A ticket created by your chatbot, your contact form, or your staff member is treated identically. No special routing, no hidden costs.

Embed Widget — One Line on Your Website

Add a floating support button to any website with one script tag:

<script src="https://coreswiftcrm.com/s/YOUR_TENANT_ID/widget.js"></script>

That gives you:

  • Floating button — bottom-right corner, matches your brand
  • Slide-out form — name, email, subject, description, priority
  • Success confirmation — visitor knows their request was received
  • No dependencies — vanilla JS, no framework, no CORS issues
  • No login required — your visitors submit tickets without accounts

Admin Support Panel

Your team manages everything from 🎫 Support in the sidebar:

  • Full queue — all tickets, filterable by status and priority
  • Create tickets — manually open tickets during phone calls
  • Reply inline — threaded messages on every ticket
  • Status workflow — open → in progress → resolved → closed
  • Priority levels — low, medium, high, urgent
  • Assignment — route tickets to team members

Customer Portal

Your end customers open 💬 My Support and see only their own requests. The portal lives at /s/<your-tenant-id>/support, and your team can open it from Support Tickets → 💬 My Support.

There is no password to issue and no email needed to sign in: the customer enters their email address plus the reference of a request they already have (the first 8 characters of the ticket id, shown on the ticket in your console). That pair proves the address, and the server hands back an access grant that never travels in a URL.

  • Submit new requests — with priority selection
  • View their history — all past tickets, statuses visible
  • Reply to open tickets — threaded conversation with your team; replying to a resolved request reopens it
  • Tenant-scoped — customers only see their own data, never another customer's and never another tenant's

This is their personal help desk — not your admin panel. They manage their own support experience.

API for Integrations

For programmatic access — connecting chatbots, Zapier, custom apps:

POST /s/:tenant_id/ticket
GET  /s/:tenant_id/widget.js
POST /api/public/contact

Set source: "agent" when creating tickets from chatbots or AI systems. The public endpoints require no authentication — designed for third-party consumption.

Pricing

Free tier: The help desk is not included — the ticket queue and the admin support panel refuse a Free workspace with 402 Payment Required (GET /api/tickets: "Support tickets is not available on your current plan"), so Support Tickets → 💬 My Support is unavailable too.
Paid tier: Support tickets (embed widget + admin support panel + customer portal) + custom domain (use your own support.yourdomain.com) + email-to-ticket parsing + priority support.

The public intake arms are not plan-gated, by decision: the embed widget script at /s/<tenant-id>/widget.js and the customer portal page are served on every plan, and a visitor's request is accepted and stored — a customer's request is never refused because of your plan, so nothing is lost either way. What a Free workspace gets instead of silence: the Dashboard shows a Customer requests you cannot open notice naming how many requests are waiting, the workspace dropdown flags them (⚠ cannot open), and GET /api/auth/me/usage carries the three fields the notice is built from (tickets, tickets_readable, support_intake_unreadable). Stored requests appear in Support Tickets the moment the plan includes it.

Chatbot integrations are API-only on all tiers — you connect your own chatbot, we handle the ticket routing.

10 Automation Features

Automation Group Overview

The Automation group (sidebar icon ⚡) contains Rules, Tags and Lead Scoring. The strategy-engine screens this section used to name are not in the console; each card below says what is API-only instead.

Agency Sequences

There is no Agency Sequences screen. Rules are read through GET /api/automation/rules; the Rules screen under Automation is the rule UI.

GET /api/automation/rules

Directory Onboarding

There is no Directory Onboarding screen. Checklist instances (entity, stage, progress, start date) are rendered on the Checklists screen under Workflow and read through GET /api/checklists/instances.

GET /api/checklists/instances

Health Monitor

Account health is computed by the API: POST /api/monitoring/account-health/check runs an analysis and GET /api/monitoring/health reads it. In the console, the platform-admin Monitoring screen renders those endpoints; there is no "Run Health Check" button in the tenant workspace.

POST /api/monitoring/account-health/check
GET /api/monitoring/health

Message Templates

Create reusable message templates for email and SMS communications. Each template has a name, channel, subject and body. Manage them in the console under Communication > Email Templates.

GET /api/comms/templates
POST /api/comms/templates
PATCH /api/comms/templates/:id
DELETE /api/comms/templates/:id

Nurture Campaigns

Contact enrollments are read through GET /api/campaigns/:id/enrollments. There is no Nurture Campaigns screen; the campaigns themselves are managed under Marketing > Campaigns.

GET /api/campaigns/:id/enrollments

11 Settings & Administration

Site Configuration (Platform Admin)

General details, SEO/meta (title, description, keywords, Open Graph) and branding colours are edited in the platform console under Admin Settings > Configuration ("Site Configuration"), which reads and writes GET/PUT /api/admin/site — server-side, not in the browser. The tenant workspace has no Settings page of its own.

Platform Console (Platform Admin Only)

Entries below the ── ADMIN ── divider appear only for a user the server marks as a platform admin (users.is_platform_admin, carried in the session as platform_admin). A tenant owner/admin role is not platform authority. The entries are:

  • Users — Every user on the platform with the workspace they belong to (read-only list).
  • Revenue > Billing & Plans — Subscription plans, pricing and limits.
  • Platform > Webhooks — a pointer to where outbound webhook endpoints are configured: each workspace registers its own in the workspace console under Settings > Webhooks (Enterprise plans). The routes are workspace-scoped, so this console has no editor for another workspace's endpoints. Also Widgets, Native Apps, Audit Log, Monitoring.
  • Communication Admin > Telnyx Admin and Private Email Admin.
  • Modules & Plans — the module registry: switch modules and individual features on or off per plan, and override a single workspace.
  • Admin Settings > Configuration — site configuration (SEO, legal pages, homepage).

There is no Impersonate button in the console: the API can start and stop impersonation, but no screen calls it.

Admin: Users & Workspaces

People live on the Users screen — every workspace's users in one list with name, email, role and joined date.

GET /api/admin/users
GET /api/admin/tenants

Admin: Plans & Feature Overrides

Modules & Plans is where each plan's modules and individual features are switched on, and where a single workspace can be granted or denied one feature without touching its plan. Enter a workspace id to load the features it effectively gets, then tick one to override it.

GET /api/admin/modules
POST /api/admin/plans/:slug/modules
POST /api/admin/plans/:slug/features
GET /api/admin/tenants/:id/entitlements
POST /api/admin/tenants/:id/overrides

Admin: Plans & Features

Plans control what features users can access. Each plan has:

  • Pricing: Monthly and yearly price, with optional payment link
  • Limits: Max contacts, deals, and users (set to -1 for unlimited)
  • Feature Toggles: the boolean flags of the module registry (the live list is here)

Available features are not a fixed list: they are the boolean flags in the module registry (modules / module_features) — the same switches the Modules & Plans panel renders. See Plans & Feature Access for the flags live today.

GET /api/billing/plans
POST /api/billing/plans
PATCH /api/billing/plans/:id
DELETE /api/billing/plans/:id
GET /api/billing/features

Admin: Telnyx Configuration (API only)

Telnyx provider settings are read and written through the API: GET /api/telnyx/config, PUT /api/telnyx/config, and GET /api/telnyx/available for the phone numbers on the account. The console's Telnyx Admin entry (Communication Admin group) is a placeholder screen today, so there is no form to paste the key into.

GET /api/telnyx/config
PUT /api/telnyx/config
GET /api/telnyx/available

Admin: Impersonation

The platform-admin API can start and stop impersonation, but the admin console has no Impersonate button yet — no screen calls it.

Note: All actions taken while impersonating are logged with the admin's identity.

Free Access & Upgrades

CoreSwift CRM offers free access with a limited feature set. When your plan does not cover something, the console shows an upgrade banner whose Upgrade Now button opens the plan comparison. Each tier that is not your current one carries a Request this plan button: pressing it sends the request to our team (nothing is charged, and no plan changes by itself) and the request names your workspace and the address to answer. Putting the workspace on a plan is therefore still an operator action — self-service checkout is not open on this install — but asking is now one press inside the app instead of a support email you had to compose yourself. Feature availability is determined by your plan's feature flags. A tier that carries a payment page also shows Open payment page: it opens that page, and pressing it files the same request first, so our team knows which workspace is paying (nothing is charged by this app).

Tip: The free plan includes the full core CRM — contacts, pipelines, automation, campaigns and SMS, calendar and bookings. Paid plans add AI scoring & helpers, private mailboxes, support tickets, and higher limits on contacts, users, pipelines and integrations.

12 Tags & Lists

Tags Overview

Tags are colored labels used to categorize contacts and companies. They support filtering, segmentation, and reporting.

Default Tag Categories: Sources, Status, Behavior each with pre-seeded tags.
CategoryDefault Tags
SourcesFacebook Google TikTok
StatusHot Lead Cold Lead
BehaviorEngaged Unresponsive
UncategorizedBooked Call Newsletter Client

Managing Tags

Go to Tags

Click Tags in the sidebar.

Create a Tag

Fill in name, select a category (or none), pick a color.

POST /api/tags
Content-Type: application/json

{ "name": "VIP", "color": "#F59E0B", "category_id": "optional-uuid" }
Assign to Contacts

Click Tags on a contact's row and pick the tag to assign.

Filter by Tag

Use the tag filter in the contacts and companies list views.

Tag Categories

Tag Categories group related tags together. Categories don't affect functionality but help organize large numbers of tags. Each tag can belong to one category or none.

Lists Overview

Lists are saved groups of contacts for targeted campaigns, email sends, or segmentation.

TypeDescription
StaticManually add/remove contacts. You pick each member.
DynamicRule-based. Contacts automatically join/leave based on criteria (score, tags, source, etc.).

Default pre-seeded lists:

  • Newsletter Subscribers (static)
  • Cold Leads (dynamic low score)
  • Hot Leads (dynamic high score)
  • Retargeting Audience (dynamic)

Managing Lists

Go to Lists

Click Lists under Marketing in the sidebar.

Create a List

Name, description, and choose static or dynamic. For dynamic, set rules.

POST /api/lists
Content-Type: application/json

{ "name": "Q3 Campaign", "list_type": "static", "description": "Targets for Q3 email blast" }
Add Members (Static)

Search for contacts and add them:

POST /api/lists/:id/members
{ "contact_id": "uuid-of-contact" }
Use the List

Lists appear as filterable segments in contacts view and can be used for campaign targeting.

13 Webhooks

Webhook Overview

CoreSwift CRM supports both incoming and outgoing webhooks for integration with satellite apps and external systems.

Satellite Apps: FunnelSwift, IncentiveSwift, WorkflowSwift, and MissedCall Respondr can push data into CoreSwift via inbound webhooks.

Inbound Webhooks (Receiving Data)

Other apps can send events to CoreSwift using authenticated webhook endpoints. The URL carries only the key prefix, which is a public index; the credential is the full key in the X-Satellite-Key header, and its SHA-256 digest must equal the digest stored for that prefix. A missing header or a wrong key is refused with 401.

POST /inbound/:key_prefix/:event_type
X-Satellite-Key: <full-api-key>
Content-Type: application/json

{ "payload": "data" }

Or the v2 endpoint:

POST /inbound/v2/:key_prefix/:event_type
X-Satellite-Key: <full-api-key>

And the v3 contact-sync endpoint — POST /inbound/v3/:key_prefix/contact-sync (also survey-complete and contact-upsert) — with the same header.

These three routes are served by the CoreSwift application itself. They are not under /api/, and the public web vhosts proxy only /api/, /s/ and /track/ to it, so on the shared host a satellite app calls CoreSwift directly rather than through the public site.

Supported event types from satellite apps:

Source AppEventAction
FunnelSwiftlead.created / lead.updatedCreates or updates a contact in CoreSwift
IncentiveSwiftentry.createdCreates contact from giveaway entry
IncentiveSwiftraffle.winnerRecords raffle winner
IncentiveSwiftloyalty.rewardRecords loyalty reward
WorkflowSwiftworkflow.completedLogs completed workflow
WorkflowSwiftinstance.advancedLogs workflow instance progression
MissedCallcall.missedCreates contact from missed call
MissedCallfollowup.createdLogs follow-up creation

Outgoing Webhook Endpoints (Sending Data)

You can register endpoints that CoreSwift will POST events to. CoreSwift delivers events to each endpoint that is active and subscribes to that event type. A workspace configures its own endpoints, signing secret and event subscriptions in the console under Settings → Webhooks: that screen lists each endpoint's name, URL, events, active state, last successful delivery and failure count, and can add, edit, pause, activate and delete them. Outbound webhooks are sold on Enterprise/Agency — a workspace whose plan lacks the webhooks module has its requests to the whole surface refused with HTTP 402 and the reason in the response body. The platform console (admin.coreswiftcrm.com) has no editor: the endpoints are workspace-scoped, so it only points here. These same calls remain available directly on the API:

POST /api/integrations/webhooks
Authorization: Bearer ***

{
  "name": "Slack Notifier",
  "url": "https://hooks.slack.com/services/xxx",
  "secret": "your-signing-secret",
  "events": ["contact.created", "opportunity.won"],
  "retry_count": 3,
  "timeout_ms": 5000
}

List configured webhooks:

GET /api/integrations/webhooks
Authorization: Bearer ***

Response: { "webhooks": [...] }

What arrives. Each delivery is a JSON POST:

POST <your url>
X-CoreSwift-Event: contact.created
X-CoreSwift-Delivery: <endpoint id>
X-CoreSwift-Delivery-Attempt: 1
X-CoreSwift-Signature: t=1759512345,v1=<hex>

{
  "event": "contact.created",
  "tenant_id": "...",
  "webhook_id": "...",
  "delivered_at": "2026-10-06T16:45:00+00:00",
  "data": { ...the event payload... }
}

Verifying the signature. When the endpoint has a signing secret the X-CoreSwift-Signature header is t=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256(secret, "<t>.<raw request body>") — compute the same value and reject a mismatch. An endpoint saved without a secret is sent unsigned.

Which events, and retries. An endpoint whose events list is empty receives every event; a non-empty list receives only those event types. An endpoint with is_active: false receives nothing. A failed delivery (anything other than a 2xx) is retried retry_count times with a growing backoff, each attempt bounded by timeout_ms; redirects are never followed. The endpoint's last_triggered_at shows its last successful delivery and failure_count how many deliveries have failed since the last success.

Integration Targets

For portfolio-level integrations, CoreSwift supports Integration Targets named connections to external systems with webhook URLs and API keys:

POST /api/portfolio/:id/targets
Authorization: Bearer <token>

{
  "name": "Mailchimp Sync",
  "provider": "mailchimp",
  "webhook_url": "https://mailchimp.com/webhook",
  "portfolio_company_id": "optional-uuid"
}

Testing a Webhook

Use the simple test endpoint to verify connectivity:

POST /simple-hook
Content-Type: application/json

{ "test": true }
Response: { "ok": true }

14 Account Settings

Account Settings

Under Settings > Profile you can view and update your profile:

  • Name Your display name
  • Email Login email — you can move it to another address yourself: Profile → Sign-in email → enter the new address, and we email a confirmation link to it. Nothing changes until you open that link (the link works once and expires in 2 hours)
  • Role admin (full access) or member (limited)

View your account:

GET /api/auth/me
Authorization: Bearer <token>

Change Password

Go to Settings > Profile

Use the Change Password card — there is no separate password tab.

Enter current password

For security verification.

Enter new password

Must be at least 8 characters.

Confirm and Save

Your token remains valid. Next login uses the new password.

PUT /api/profile/password
Authorization: Bearer <token>

{ "current_password": "<your-current-password>", "new_password": "NewSecurePass123!" }
Forgot your password? Use the forgot-password flow on the login screen: POST /api/auth/forgot-password with your email. Check your inbox for a reset link.

Organization Settings

Your organization has its own profile:

  • Name Your company/org name
  • Slug URL-friendly identifier
GET /api/account/:id — View details
PATCH /api/account/:id — Update name

API Keys

API keys allow satellite apps to authenticate when sending data to CoreSwift via webhooks. Each key has:

  • Key Prefix The leading characters of the key, carried in the webhook URL to select the row. It is public and is not a secret.
  • Full Key The credential, sent in the X-Satellite-Key header. The server stores only its SHA-256 digest (key_hash), compares the two in constant time, and can never recover the full key from the row.
  • Source App Which app this key is for (funnelswift, incentiveswift, etc.)
  • Status Active or Disabled (a disabled key authenticates nothing)
  • Last Used Timestamp of most recent usage

Satellite keys have no console screen: they are provisioned per tenant by the operator, who stores the prefix and the SHA-256 digest of the full key in the satellite_api_keys table (key_prefix, key_hash, source app, active flag, last used). The keys a workspace mints itself are the Lead-delivery keys (csk_…) in Settings > Integration Center, backed by POST /api/personal-api-keys (list, rotate and revoke alongside).

Portal & Portfolio Companies

For agency-level accounts, CoreSwift supports:

  • Portfolio Companies Track multi-tenant clients under your agency (GET/POST /api/portfolio)
  • Cross-App Sync Push data between apps: POST /api/admin/portfolio-sync
  • Impersonation Admin can impersonate a user: POST /api/admin/impersonate

15 Themes & Appearance

One built-in look

There is no preset-theme picker and no Appearance screen in the console today — the workspace ships a single built-in look. (A widget's own form carries an accent colour for that widget.)

16 Deal Reminders

Not in the console today

There is no reminder control on a deal, no reminder panel on the dashboard and no Overdue count, and no route that lists or creates reminders — so there is nothing to set up here yet.

17 Revenue Forecast

Not in the console today

There is no Forecast screen and no forecast endpoint, so no weighted-pipeline view is shown anywhere. Deal value by stage is visible on Sales > Pipelines & Deals, which lists each pipeline's deals with its won / open / lost counts.

18 Deal History

What is recorded

Every stage move is written down as it happens — which stage it moved from and to, and who moved it — so a deal's progression is kept.

What the app shows

The CRM has no Activity Timeline screen, and no endpoint that lists a deal's history, so that history is not visible in the app today. Platform-wide events (type, description, related entity, date) can be read through the API:

GET /api/events

19 CSV Import & Export

Import Contacts from CSV

Migrate your existing contacts from any CRM or spreadsheet with a single CSV import:

  1. Go to Contacts and click ⬆ Import CSV.
  2. Upload your CSV via drag-and-drop or file browser.
  3. Preview — CoreSwift reads the header row and shows you a preview of how fields will be mapped.
  4. Batch Import — Click Import and the system creates contacts in bulk (up to 500 per batch).

Export to CSV

Two tables export to CSV: your contacts and your deals.

  • From Contacts — Click ⬇ Export CSV on the Contacts screen to download all contacts as CSV
  • From Pipelines & Deals — Click ⬇ Export deals to download every deal in the workspace as CSV, with its contact, company, pipeline and stage names

Import Deals from CSV

The same header row the export writes can be loaded straight back in, so an export doubles as a backup you can restore:

  1. Go to Pipelines & Deals and click ⬆ Import deals.
  2. Choose your file — the console shows every column it recognised and a few sample rows before anything is written.
  3. Click Import deals — the board refreshes with the new cards, and the toast reports how many landed and how many were skipped.

Each row needs a name. pipeline and stage are used when the file names ones that exist; otherwise the row goes into your first pipeline. A contact is linked only when its email or full name matches an existing contact. A file with no name column is refused by the console instead of importing nothing.

Auto-Create Contact from Deal

The New Deal dialog links the deal to one of your existing contacts from a dropdown; it has no inline name/email/phone fields, so create the contact first if it is missing.

This pattern is also available in sister apps (FunnelSwift and IncentiveSwift) for seamless lead-to-deal creation.

Supported CSV Columns

Column HeaderMaps To
nameContact Name (required)
emailEmail Address
phonePhone Number
companyCompany Name
titleJob Title
notesNotes / Description
tagsComma-separated tag names (auto-created)

CoreSwift CRM — v0.1.0

Built by SwiftSoftware | coreswiftcrm.com

Customer Relationship Management Platform · API /api/


🤝 Affiliate Program

Earn commissions! Refer other businesses to this service and earn a percentage of their subscription fees. The affiliate system is managed through FunnelSwift — ask your account manager to set up your affiliate account.

How It Works

  1. Get Your Affiliate Link

    Your affiliate manager provides a unique tracking link (or you can generate one in the FunnelSwift affiliate portal).

  2. Share It

    Post the link on your website, in emails, on social media, or wherever your audience is.

  3. They Sign Up & Pay

    When someone clicks your link and later completes a paid purchase, the system tracks the conversion.

  4. You Earn Commission

    Commissions are calculated based on your affiliate rate and credited to your account automatically.

Products You Can Promote

Commissionable products live in the affiliate portal (FunnelSwift → Affiliate Products) and that list is the source of truth — a paid plan of any service can only be promoted once an admin has added it there. Platform-wide entries are visible to every affiliate; a workspace's own products are visible to its affiliates. Measured 2026-09-26, the catalogue holds:

ScopeProductPrice
All affiliatesCoreSwift Free$0
ADASwift Free$0
IncentiveSwift Free$0
MissedCall Respondr Free$0
WorkflowSwift Free$0
FunnelSwift workspaceCapture Free$0
Capture Starter$9/mo
Kinetic Free$0
Kinetic Pro$9/mo
Suite$29/mo
Agency / Scale$79/mo

The rate earned on a sale is your own affiliate rate — the one on your affiliate account — not a per-product figure. Products, prices and rates are edited on the product record in the portal, so the portal is always the current list.

Conversion Tracking

Attribution lives in FunnelSwift. The trigger is a plan change in this app — there is no checkout session and no payment-provider webhook anywhere in the chain:

  1. The Referral Is Recorded

    When someone arrives through your affiliate link, FunnelSwift keeps them as a lead on your affiliate account. That lead is the attribution — it is permanent, with no cookie to expire or be lost.

  2. CoreSwift Reports the Plan Change

    When the referred business moves to a paid plan here (the CoreSwift platform admin assigns the plan to the workspace — POST / PATCH /api/billing/subscription are operator-only writes, with no customer self-service plan change), CoreSwift looks up the account owner's email address and posts it to FunnelSwift's internal affiliate endpoint, POST /api/v1/internal/affiliate/upgrade-event, together with the plan name and its price.

  3. Commission Recorded

    FunnelSwift matches that email back to the lead, applies the affiliate's rate to the plan price, and records the commission against the event. A repeat of the same upgrade event is ignored, so nothing is credited twice.

This is fully automatic — nothing extra is needed as long as the customer reaches you through your affiliate link. Two details worth knowing: attribution is matched by the email address the referred business signed up with, and only a move onto a paid plan counts as an upgrade.

Managing Affiliates

Affiliates are managed through the FunnelSwift Admin portal:

To access, log in to FunnelSwift and navigate to Super Admin → Affiliate Admin.

21 Plans & Feature Access

Your admin decides what each plan includes

Features are not hard-coded. Each plan carries a set of feature flags, and every flag can be switched on or off per plan by an admin — so a Free tier can be a genuinely stripped-down CRM while Enterprise unlocks everything. A single tenant can also be given a per-tenant override without changing the plan itself.

When a feature is switched off for your plan, its API returns 402 Payment Required with a message naming the feature, and the corresponding area of the app is unavailable until the plan is upgraded. Features you do have are untouched.

Flags an admin controls

FlagFeatureModuleNotes
campaignsCampaignscampaignsSequenced email campaigns
automationAutomationsautomationTrigger/action engine
checklistsChecklistschecklistsOnboarding/process checklists
ai_enabledAI scoring & helpersai_enabledLead scoring and AI helpers
ticketsSupport ticketsticketsIn-house ticketing + email-to-ticket
native_appsNative app connectorsnative_appsFunnelSwift, ADASwift, MissedCall, WorkflowSwift, Multi-Directory
telnyxSMS & voice (Telnyx)telnyxSMS, number management, call tracking
round_robinRound-robin routinground_robinFair lead distribution across a team
eventsEvent systemeventsInternal event bus
monitoringMonitoring & healthmonitoringAccount health scoring and thresholds
bookingsBookings & schedulingbookingsCalendar booking pages
google_calendarGoogle Calendar syncgoogle_calendarTwo-way calendar sync
api_accessAPI accessapi_accessPer-tenant API keys
webhooksWebhookswebhooksOutbound webhook delivery
integrationsIntegrationsintegrationsn8n and third-party integrations
provider_keysProvider keysprovider_keysBring-your-own provider credentials
support_widgetsSupport widgetssupport_widgetsEmbeddable support surfaces
tracked_linksTracked linkstracked_linksClick tracking links
private_emailPrivate mailboxprivate_emailOwn domain + mailboxes (also has its own limits)
email_sendingEmail sendingprivate_emailWhether this plan may SEND mail from its mailboxes (receiving is always allowed)
portfolioPortfolio syncportfolioCross-tenant portfolio management
account_matchAccount matchingaccount_match
notificationsNotificationsnotifications
notifications_in_appIn-app notificationsnotifications
notifications_emailEmail notificationsnotifications
notifications_smsSMS notificationsnotifications
notifications_whatsappWhatsApp notificationsnotifications

Source of truth: the module registry in the API's database (modules / module_features) — the same switches the admin panel renders, served by GET /api/admin/modules. If a flag is registered there it appears here and in the admin automatically.

22 Modules & Connectors

Connections to your other apps

CoreSwift is the CRM hub for the rest of the ecosystem. Each connector is a native integration — no third-party middleware:

Each connector can be connected/disconnected and synced per tenant, and is gated by the native_apps flag above.

Private Email

Bring your own domain (Mailgun, SMTP, SES or Postmark), provision mailboxes such as info@yourcompany.com, send through your provider's DKIM/SPF signing (the provider signs each message — this app hands it over and never signs it itself), and have inbound replies create contact activity on the CRM timeline. Domain and mailbox counts are plan limits; provider credentials are encrypted at rest.

Also included

Not in this app: spreadsheet import/export is CSV only (XLS/XLSX are not supported), and there is no newsletter/mailing-list sender — campaigns and private email cover outbound email.

23 Tag to free account

When a lead is tagged in FunnelSwift with one of this app's tags — for example CoreSwift — Free — CoreSwift is told to create a free account for that lead, using the same name and email the lead was captured with. CoreSwift emails the new user their login details automatically, so they can sign in and upgrade here whenever they are ready.

What happens when it is ON

What happens when it is OFF

The tagged lead is still recorded here as a contact, so nothing is lost, but no account is created and no login email is sent. Use this if you want to review leads before accounts exist for them.

Where the switch is

Operators turn this on or off in the admin console, under Provisioning → Tag Provisioning.

FunnelSwift is the hub where affiliates and leads live. Tagging is how a lead is routed to the software they are interested in; the account is created here, in the destination app, so the lead signs in at the app they actually want and upgrades on this app's own plans.

Email branding

Settings → Email Branding puts this workspace's own logo, display name and colour on every transactional email it sends — the welcome/credentials mail, password resets and purchase confirmations. The branding is this account's; nothing is shared with another workspace.

An account with neither a name nor a logo gets exactly the mail it got before this feature existed. Removing the logo keeps the name and the colour.

Workspaces

Sidebar → Workspaces (in the Settings group) lists this account’s workspaces. A workspace is a name — a label you give a part of the business, such as “Miami office” or “Wholesale” — and the one marked Default is the workspace a new session is meant to open.

If your plan states a workspace limit, adding past it says so and points you at the plan screen; nothing is created and nothing is lost.

Team & Invites

Sidebar → Team & Invites is how a second person gets a real login INTO this workspace. Only the workspace owner and an admin can see it.

  1. Add a teammate. Type their email address (their name is optional) and choose what they can do: Member works inside the workspace; Admin can also invite people and manage the workspace. Press Send the invitation.
  2. We set their password and email it to them. There is no password field anywhere on this screen, and you never choose or see their password. They sign in at the normal login page with the address and password that email carries, and they land on the Dashboard; their mail is one press away in the Shared Inbox tab.
  3. They work in the same account. A member sees the workspace’s contacts, pipeline and mail exactly as the owner does, except owner-only screens such as Team & Invites.

Who is looking after what. The Shared Inbox tab lists every address with an Assigned to column: pick a teammate there to make an inbox theirs, or leave it empty to keep it with the whole workspace. Open any conversation and the same Assigned to choice sits on the message. That one answer is also what the Support Tickets queue shows, so a conversation never ends up with two owners in two different systems.

Removing somebody takes their access away at their next click — the session they already hold stops working — and puts their conversations and inboxes back in the workspace. Nothing is deleted: their mail, the tickets they worked and every message stay exactly where they are. The workspace owner cannot be removed this way.

Seats follow your plan. Each plan states how many people it includes. When every seat is in use, Send the invitation answers with the plan that adds more seats and what it costs — for example, “Your plan includes 1 person, and 1 is already in use. Starter raises that to 3 people for $29/month, and you can invite them right away” — and nothing is charged by itself. If the email carrying the password cannot be sent, the list of people says so next to that person, and they can use Forgot password on the login page to choose their own.

A seat is one person who can sign in to this account, and the owner counts as one. On this plan ladder the number of people is: Free 1, Starter 3, Professional 15, Enterprise 20, Agency 100. Pro (5 seats) and the $1 mailbox line are not on sale — neither appears in Plans & Billing and neither can be bought today — and the $1 mailbox includes no second person. Removing a teammate frees their seat at once, so you can add somebody else the same day.

A link still works too. A teammate who would rather pick their own password can use Create invite link under the form: the link stays valid for 7 days and works once.

Your calendar address

Your workspace has a public calendar address from the day it is created: <your-workspace>.coreswiftcrm.com. Anyone you give it to sees your open booking calendars, how many places are left and a form to reserve one — no account, no sign-in. It works immediately; there is nothing to switch on.

Open Calendar in the console and look at the card Your public calendar address:

The page is public: it shows only the calendars you have marked active and the places that are still open. A booking someone sends from it appears in Bookings like any other.

Your inbox: bring your own domain

CoreSwift does not give out an address on our domain. You keep the domain you already own (for example yourbusiness.com) and your own Mailgun account, and your mail is delivered straight to you. Open the Shared Inbox tab in the console: the setup page is the onboarding, in three plain steps, with a copy button beside every value.

  1. Add your domain and make two choices. Type the domain, choose how it sends and how it receives, and paste only the keys those choices need. Both keys are stored sealed and used only for your own mail.
  2. Add the records at your own DNS host (Cloudflare, or your registrar). Three groups: MX — mxa.mailgun.org and mxb.mailgun.org, where mail is delivered; SPF and DKIM — v=spf1 include:mailgun.org ~all plus the DKIM value your own Mailgun mints, which prove the mail is really from you; and one CNAME — inbox → inbox.coreswiftcrm.com, which makes inbox.yourbusiness.com open your mail. Every row carries a copy button, one sentence saying what it does, and a live Active / Waiting / Needs attention badge. Press Check again after adding them.
  3. Create your inbox. The button stays disabled until receiving and sending both verify, because an address that cannot receive is worse than no address at all. Nothing is charged and no mailbox exists until then.

Inboxes follow your plan. Free 1, Starter 3, Professional 10, Enterprise 50, Agency 50 — and the setup page states your own number, read from the plan itself, so it can never promise more or fewer than the app will actually create. When you are already at that number, Create new inbox answers with the plan that unlocks more and what it costs, never a dead button.

One difference on Cloudflare: the mail records must be DNS only (grey cloud) — the orange proxy breaks mail. The inbox CNAME is the one exception: it must be Proxied (orange cloud), because Cloudflare then serves the padlock on your own address.

Logging in at the mail client takes you to a mailbox chooser. The screen is headed Choose a mailbox and lists one card per address you created, each card carrying the address and how many messages it holds; pick one and it opens. Signing in to the CRM lands on the Dashboard instead — open the Shared Inbox tab, which lists the same inboxes, each row with a LOG IN button on the right that opens your mail in a new window — at inbox.yourbusiness.com once that record is live, or at inbox.coreswiftcrm.com until it is — plus a Create new inbox button.

Your 30 free days start at your first verified inbox, not at signup: the days you spend waiting on DNS cost you nothing. During the trial, sending has a fair-use ceiling of 200 messages a day to protect the address’s deliverability.

When the 30 days end the address keeps working and keeps receiving. Nothing is deleted. What stops is sending — the mailbox becomes receive-only and the screen offers two buttons: Keep inbox — $1/mo (the mailbox alone) and Upgrade CRM (the whole platform). Upgrade CRM restores sending immediately. The $1 mailbox line is not on sale yet: pressing it opens its plan with a note that sales are not open and reaches our team, and nothing is charged. Every message you already have stays where it is.

What “receive-only” means in plain words: mail keeps arriving and you keep every message you already have. Only Compose and Reply stop, and both answer with the two buttons above rather than an error. Nothing is deleted at expiry, by pressing the wrong button, or by waiting — there is no deadline after which mail disappears.

One bill, never two. The $1 mailbox line is a standalone door, not an add-on. It is not on sale yet — it is absent from Plans & Billing, and pressing its card answers that sales are not open, without charging anything — so no workspace pays it today. If it does go on sale: moving up to a CRM plan ends the $1 subscription in the same step, so you pay the new plan’s price only — never $1 on top of it — and the new period starts the day you move, so nothing is prorated. Plans & Billing opens with Your bill, which states the one amount you pay, that there is one subscription, and — if your plan changed — the line that ended and the day it ended.

When your plan already includes every inbox you have, Create new inbox answers with the plan that unlocks more and what it costs, never a dead button. The $1 single-inbox line is not on sale yet — its card reaches our team and charges nothing — so move up the CRM plans for more addresses.

Sending and receiving are two separate choices

You do not have to move your mail to one company. The inbox setup page asks two questions that stand on their own: how should your mail leave (sending) and how should your mail arrive (receiving). Every option in those two lists really works — there is no placeholder in either one.

Mixing them is normal. Sending through Amazon SES while receiving through Mailgun — or sending through Mailgun and receiving through SendGrid — is a supported setup, and it is the one that lets you keep whatever already sends your mail. Changing one never changes the other.

Receiving through SendGrid

  1. Add the domain on the setup page and choose Receiving: SendGrid. No SendGrid key is needed: SendGrid posts each message to an address we give you.
  2. At your DNS host add one MX record pointing your domain at mx.sendgrid.net with priority 10. If your domain is on Cloudflare, leave it DNS only (grey cloud).
  3. Copy the SendGrid Inbound Parse address the setup page shows you — ours, ending in a long private code — then in SendGrid open Settings → Inbound Parse, add your domain and paste it as the destination.
  4. Press Check again. The receiving group turns Active once your domain’s mail really points at SendGrid, and that is when the inbox can be created.

That address is a password. SendGrid’s Inbound Parse signs nothing, so the address itself is the only thing proving a delivery is genuinely yours: anyone holding it can post mail into your inbox. Keep it out of tickets and screenshots, and never put it on a page.

Your sending records stay yours. When you receive through SendGrid, the SPF and DKIM records remain exactly as your sending service gave them — Amazon SES mints its own, SendGrid mints its own, Mailgun mints its own. The setup page says where they come from instead of inventing them. If the same domain also sends through Mailgun, Mailgun’s own sending records are shown, because they are yours and we can read them.

Switching later

Receiving can be changed without touching sending. The setup page shows Change how this domain receives under the domain; pick Mailgun, SendGrid or Nowhere. Nothing already received is deleted and your sending keys are untouched. Switching to SendGrid issues that domain’s Inbound Parse address if it did not have one.

Your own Mailgun account: the two keys, and where to copy each one

Two keys, two different jobs, and neither is a password you use to sign in here. You paste both once, on the inbox setup page; the app stores them sealed (encrypted) and uses them only for your own mail. Both are copied from your own Mailgun account.

A wrong or rotated key is visible, not silent. Paste a new value at any time on the same screen; the old one stops being used the moment it is saved. If Mailgun stops accepting a key, that domain’s badge reads Needs attention with a sentence saying what Mailgun answered, and the rest of the app keeps working.

Catch-all: one address that catches everything

What it is. Normally mail is accepted only for an address you created, such as info@yourbusiness.com; a message to nobody@yourbusiness.com is refused at the door. Catch-all accepts every message sent to your domain, even when that address does not exist, and files it in your inbox under Everything else (labelled MISC).

When to use it. Turn it on when people write to addresses you never created on purpose — sales@, billing@, a mistyped inof@, the address printed on an old business card — and you would rather read that mail than have it bounce. Leave it off when you want silence: with catch-all off, mail to an unknown address is refused, which is also how a sender learns they have the wrong address.

How to switch it. Sidebar → Inbox → Email Domains & Sending, find the domain and use its Catch-all column: Enable catch-all turns it on, Disable turns it off. It is set per domain, so two domains on one account can differ.

It follows the plan, not the domain. On this plan ladder catch-all is included from Professional ($79) upward — Professional, Enterprise and Agency — and is not sold on Free or Starter. Pressing the button on a plan that does not include it answers with the plan that unlocks it and what it costs, and nothing changes. If the workspace later moves back to a plan without it, your setting is remembered but mail to an unknown address is refused again; the column then reads off — not on your plan, with a Clear button that forgets the setting.

What catch-all is not. It does not create addresses. A catch-all message is not a mailbox, cannot be signed into, and does not start a trial — it is one bucket inside the inbox you already have.

Your logo and signature on outgoing mail

One logo and one workspace signature, both applied automatically. Open Email Branding in the workspace menu: upload the company logo, then fill in the signature — name, title, company, phone and one short line — and press Save signature. From then on every new message and every reply opens with the logo and the signature already in place under the text you type, so you type only the subject and the message.

You never size the logo. Any PNG, JPEG, GIF or WebP up to 2 MB is accepted and the app resizes it for email, so it looks sharp and the right size in Gmail, Outlook and Apple Mail on a phone as well as on a desktop. The preview on the Email Branding screen shows what your customers will see.

Per address, if you want. In the mail client press Signature and choose, for one address: use the workspace signature, write its own wording (a blank field falls back to the workspace value for that field), or send without a signature — useful for a no-reply address. Every other address keeps following the workspace signature.

Leave it off one message. The compose window shows the signature under the message with an Include the signature on this message box already ticked. Untick it and that one message — or that one reply — goes without the signature. Nothing is saved, so the next message starts signed again.

Changing or deleting the logo never breaks mail you already sent. The logo travels inside each message rather than being fetched from a link, so a message sent last month still shows the logo it was sent with even after the logo is replaced or removed. New messages use the new logo immediately.

Storage: the meter, the three warnings, and what a full mailbox does

Every account has a storage allowance, and it grows with the plan. Free starts at 2 GB; Starter 10 GB, Professional 50 GB, Enterprise 100 GB and Agency 250 GB. (Pro and the $1 mailbox line carry 10 GB and 5 GB in the catalogue but are not on sale, so they are not part of this ladder.) Storage counts the mail you have received and sent, plus the logo and profile pictures you upload.

The meter is on the mail screen all the time, at the bottom of the left-hand column, and it states the real figures — for example “1.5 of 2 GB used (75%)” — never just “storage”.

You are warned three times, and at most once per level per month. At 50%, 75% and 99% full a banner appears above the message list and stays there until space is freed. The account owner also gets one email per level per month, carrying the same numbers, what to do, and a link to the mail screen and the plans. The same level is never emailed twice in one month.

When the reminders arrive. The figures are checked whenever you open your mail, and again in the background every ten minutes, so a mailbox nobody opens is still warned by email. One email per level per month is the most you will ever receive — the same level cannot be mailed twice in one month, however much mail arrives in between.

A full mailbox never loses mail. At 100% plain mail still arrives and is stored, sending still works, and nothing is deleted to make room. The only thing that pauses is adding a new attachment or file (for example uploading a logo): that answers with a sentence naming the figures and the two ways out — delete or archive mail (Trash and Spam count toward the figure until emptied), or upgrade for more storage. Everything works again the moment the figure drops below the allowance.

Time-based retention is only a far backstop. Mail is not removed on a clock: the default backstop is ten years (3,650 days), and the mail screen always states the window that applies to the account, together with the date the oldest message would reach it. Freeing space is always your choice — by deleting or archiving — never an automatic purge to make room.

Seeing a domain's DNS records, and removing a domain you no longer want

Every domain on Email Domains & Sending has two buttons beside its verification badge.