MisarMisar Docs
MisarMailMisarBlogMisarReachMisarPostMisarDevMisarCoderMisarSEOMisar PlatformMisar SSO
API Reference

Accounts

Connect and manage IMAP/SMTP email accounts, share them, and check sender reputation

Email accounts are the connected mailboxes used for inbox sync and as sending identities. Each account stores IMAP/SMTP settings and an encrypted password, and belongs to the authenticated user (accounts can also be shared with other users).

Account endpoints use session authentication (dashboard cookie), not API-key auth. To send programmatically via API key, use POST /api/v1/send. The reputation endpoint is the exception — it accepts a bearer token (see below). Base URL: https://api.misar.io/mail.

List connected accounts

GET/mail/accounts

List all email accounts the user owns or that have been shared with them.

Response fields

successboolean

true when the request succeeded.

dataarray

Accounts. Each includes id, email, display_name, imap_host, smtp_host, last_sync_at, sync_status, signature, is_default, created_at, user_id, and the booleans isOwned / isShared.

sync_status values: idle (default, no sync in progress), syncing (actively syncing inbox), synced, error (IMAP connection failed — check credentials).

Request
curl https://api.misar.io/mail/accounts \
  -H "Cookie: sb-access-token=YOUR_SESSION"
200 — OK
{
  "success": true,
  "data": [
    {
      "id":           "550e8400-e29b-41d4-a716-446655440000",
      "email":        "hello@yourdomain.com",
      "display_name": "Your Name",
      "imap_host":    "imap.yourdomain.com",
      "smtp_host":    "smtp.yourdomain.com",
      "last_sync_at": "2026-01-15T10:05:00Z",
      "sync_status":  "idle",
      "signature":    null,
      "is_default":   true,
      "created_at":   "2026-01-15T10:00:00Z",
      "user_id":      "user_abc...",
      "isOwned":      true,
      "isShared":     false
    }
  ]
}

Connect a new account

POST/mail/accounts

Connect a new IMAP/SMTP email account. Request fields are camelCase; host/port fields default to MisarMail's servers when omitted.

Request body

emailstringbodyrequired

The email address of the account (≤254 chars).

passwordstringbodyrequired

IMAP/SMTP login password or app password (min 8 chars, stored encrypted).

displayNamestringbody

Display name for outgoing emails (≤255 chars).

imapHoststringbodydefault: mail.misar.io

IMAP server hostname.

imapPortintegerbodydefault: 993

IMAP port.

smtpHoststringbodydefault: mail.misar.io

SMTP server hostname.

smtpPortintegerbodydefault: 587

SMTP port.

signaturestringbody

Default signature appended to outgoing mail (≤5000 chars).

isDefaultbooleanbodydefault: false

Make this the default sending account.

workspaceIdUUIDbody

Associate the account with a workspace.

Response fields

successboolean

true when the account was connected.

dataobject

The created account: id, email, display_name, imap_host, smtp_host, is_default, and created_at.

Request
curl -X POST https://api.misar.io/mail/accounts \
  -H "Cookie: sb-access-token=YOUR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{
    "email":       "hello@yourdomain.com",
    "displayName": "Your Display Name",
    "imapHost":    "imap.yourdomain.com",
    "imapPort":    993,
    "smtpHost":    "smtp.yourdomain.com",
    "smtpPort":    587,
    "password":    "your-email-password"
  }'
201 — Created
{
  "success": true,
  "data": {
    "id":           "550e8400-e29b-41d4-a716-446655440000",
    "email":        "hello@yourdomain.com",
    "display_name": "Your Display Name",
    "imap_host":    "imap.yourdomain.com",
    "smtp_host":    "smtp.yourdomain.com",
    "is_default":   false,
    "created_at":   "2026-01-15T10:00:00Z"
  }
}
409 — Already connected
{ "error": "Email account already exists" }

Update an account

PATCH/mail/accounts

Update an account you own. The account id is passed in the body.

Request body

idUUIDbodyrequired

ID of the account to update.

displayNamestringbody

New display name.

signaturestringbody

New default signature.

isDefaultbooleanbody

Make this the default sending account.

Response fields

successboolean

true when the update succeeded.

dataobject

The updated account.

Request
curl -X PATCH https://api.misar.io/mail/accounts \
  -H "Cookie: sb-access-token=YOUR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{ "id": "550e8400-...", "isDefault": true }'

Disconnect an account

DELETE/mail/accounts

Disconnect an account and stop inbox sync. The account id is passed as a query parameter, not a path segment. Already-synced emails are not deleted.

Query parameters

idUUIDqueryrequired

ID of the account to disconnect.

Response fields

successboolean

true when the account was disconnected.

Request
curl -X DELETE "https://api.misar.io/mail/accounts?id=550e8400-e29b-41d4-a716-446655440000" \
  -H "Cookie: sb-access-token=YOUR_SESSION"
200 — OK
{ "success": true }

Status codes

  • 200 — OK. List, update, delete, or reputation request succeeded.
  • 201 — Created. Account connected.
  • 400 — Bad request. Validation failed (with details), Account ID is required, or Invalid account ID format.
  • 401 — Unauthorized. No active session (or missing bearer token on the reputation endpoint).
  • 403 — Forbidden. The account is not yours, or your plan's email_accounts limit is reached.
  • 404 — Not found. Account not found.
  • 409 — Conflict. Email account already exists.
  • 500 — Server error. Retry.

Get sender reputation

GET/mail/accounts/reputation

Returns cached reputation signals for your connected accounts. This endpoint authenticates with a bearer token (Authorization: Bearer <token>), not the session cookie.

Headers

Authorizationstringheaderrequired

Bearer <token>

Response fields

accountsarray

Per-account reputation. Each row includes the account's reputation columns plus a derived severity. reputation_score is categorical — one of high, medium, low, or none — and reputation_suspicious is a boolean flag.

summaryobject

Roll-up counts: total, critical, warning, good, and unknown.

Request
curl https://api.misar.io/mail/accounts/reputation \
  -H "Authorization: Bearer YOUR_TOKEN"
200 — OK
{
  "accounts": [
    {
      "id": "550e8400-...",
      "email": "hello@yourdomain.com",
      "reputation_score": "high",
      "reputation_suspicious": false,
      "severity": "good"
    }
  ],
  "summary": { "total": 1, "critical": 0, "warning": 0, "good": 1, "unknown": 0 }
}

Trigger a fresh reputation check for one account with POST /mail/accounts/reputation and a body of { "id": "<accountId>" }. It returns that account's refreshed row with its severity. Errors: 400 Missing account id, 404 (not found), 502 (upstream check failed).

Account sharing

Accounts can be shared with other MisarMail users. Sharing uses a permission model — owner, admin, editor, or viewer (default viewer) — issued via invitations that the recipient accepts or declines.

List account invitations

GET/mail/accounts/:id/invitations

List invitations issued for this account. Account owner only.

Path parameters

idUUIDpathrequired

ID of the account.

Response fields

successboolean

true when the request succeeded.

dataarray

Invitations. Each includes id, invitee_email, invitee_user_id, permission, status, message, expires_at, accepted_at, and created_at.

200 — OK
{
  "success": true,
  "data": [
    {
      "id": "inv_abc123",
      "invitee_email": "colleague@example.com",
      "invitee_user_id": null,
      "permission": "viewer",
      "status": "pending",
      "message": "Join our shared mailbox",
      "expires_at": "2026-06-20T10:00:00Z",
      "accepted_at": null,
      "created_at": "2026-05-20T10:00:00Z"
    }
  ]
}

Invite a user to an account

POST/mail/accounts/:id/invitations

Invite another MisarMail user to access this account. Account owner only. Only owners can grant the owner permission.

Path parameters

idUUIDpathrequired

ID of the account.

Request body

emailstringbodyrequired

Invitee's email address.

permissionstringbodydefault: viewer

One of owner, admin, editor, viewer.

Request
curl -X POST https://api.misar.io/mail/accounts/550e8400-.../invitations \
  -H "Cookie: sb-access-token=YOUR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{ "email": "colleague@example.com", "permission": "editor" }'

Revoke a pending invitation with DELETE /mail/accounts/:id/invitations (account owner only).

List account shares

GET/mail/accounts/:id/shares

List active shares (accepted access) for this account. Account owner only.

Path parameters

idUUIDpathrequired

ID of the account.

Response fields

successboolean

true when the request succeeded.

dataobject

ownerId, accountEmail, and shares — each share with id, user_id, permission, granted_by, and granted_at.

200 — OK
{
  "success": true,
  "data": {
    "ownerId": "user_owner...",
    "accountEmail": "hello@yourdomain.com",
    "shares": [
      {
        "id": "share_01hv...",
        "user_id": "user_abc...",
        "permission": "editor",
        "granted_by": "user_owner...",
        "granted_at": "2026-05-21T14:00:00Z"
      }
    ]
  }
}

Revoke an active share with DELETE /mail/accounts/:id/shares. Add a share directly (owner only) with POST /mail/accounts/:id/shares.

List pending invitations received

GET/mail/invitations/pending

List all pending invitations the current user has received (across accounts). Powers the dashboard's "You've been invited" banner.

Response fields

successboolean

true when the request succeeded.

dataarray

Received invitations. Each includes id, account_id, inviter_id, invitee_email, permission, status, message, token, expires_at, and created_at.

200 — OK
{
  "success": true,
  "data": [
    {
      "id": "inv_abc123",
      "account_id": "550e8400-...",
      "inviter_id": "user_boss...",
      "invitee_email": "me@example.com",
      "permission": "admin",
      "status": "pending",
      "message": null,
      "token": "tok_...",
      "expires_at": "2026-06-20T10:00:00Z",
      "created_at": "2026-05-20T10:00:00Z"
    }
  ]
}

Accept or decline an invitation

POST/mail/invitations/decline

Decline a pending invitation. To accept instead, POST /mail/invitations/accept with the same body.

Request body

invitation_idUUIDbodyrequired

ID of the invitation.

Request
curl -X POST https://api.misar.io/mail/invitations/decline \
  -H "Cookie: sb-access-token=YOUR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{ "invitation_id": "inv_abc123" }'
404 — Not found
{ "error": "Invitation not found" }

Declining fails with 400 if the invitation is no longer pending or was sent to a different email address than the signed-in user.