Eviworx
Docs

Inbound Mailboxes API

A mailbox connects an email address to the helpdesk: Eviworx polls it, turns every mail into a record and sends replies back the same way. Every mailbox carries its own configuration — receive and send path, defaults for new tickets, limits, post-processing in the mailbox and an optional access restriction. All of it is managed under /api/inbound-mailboxes. How a mail travels through the system is described on the Email System page.

📮
Features
✓ Any number of mailboxes side by side
✓ IMAP or Microsoft Graph for receiving
✓ SMTP or Microsoft Graph for sending
✓ Per-mailbox defaults for new tickets
✓ Limits per mailbox instead of globally
✓ Live connection probe and folder list
✓ Per-mailbox access restriction
✓ Backlog and error reason in the operating state

Permissions

Permission Allows
inboundMailboxes.viewRead mailboxes and their operating state
inboundMailboxes.createCreate a mailbox
inboundMailboxes.editChange a mailbox and query the server folder list
inboundMailboxes.deleteDelete a mailbox — critical permission (revocation takes effect immediately, denied calls are logged)
inboundMailboxes.testConnectionProbe the receive path
inboundMailboxes.testSmtpProbe the send path
inboundMailboxes.manageAccessSet the access restriction and grant access — critical permission, because it opens the ticket visibility across all mailboxes
tickets.changeMailboxHand a ticket over to another mailbox; additionally opens the option list of all active mailboxes

Endpoints

Method Endpoint Response Permission
GET/api/inbound-mailboxesAll mailboxes — { data }, newest first; includes deactivated onesview
GET/api/inbound-mailboxes/optionsLean option list — { data } with id, name, emailAddressany login
GET/api/inbound-mailboxes/:idA single mailboxview
POST/api/inbound-mailboxesCreate → 201create
PUT/api/inbound-mailboxes/:idUpdate — partial changes allowededit
DELETE/api/inbound-mailboxes/:idDelete → 204delete
POST/api/inbound-mailboxes/:id/test-connectionProbe the receive path → { connected: true }testConnection
POST/api/inbound-mailboxes/:id/test-smtpProbe the send path → { connected: true }testSmtp
GET/api/inbound-mailboxes/:id/foldersFolders on the server — { data } with folder pathsedit
GET/api/inbound-mailboxes/:id/restriction{ mailboxId, isRestricted }view
PUT/api/inbound-mailboxes/:id/restrictionSwitch the restriction on/off → { mailboxId, isRestricted }manageAccess
GET/api/inbound-mailboxes/:id/access{ mailboxId, isRestricted, accessList }manageAccess
POST/api/inbound-mailboxes/:id/accessGrant access → 201manageAccess
DELETE/api/inbound-mailboxes/:id/access/:accessIdRevoke access → 204manageAccess

Reading and probing are open to API keys as well; every mutation requires a logged-in person and answers an API key with 403. The option list is the exception among the read paths: its scope is user-specific, so it is user-bound too.

The list has neither filters nor pages — there are few entries and the administration needs all of them. Deleting is a soft delete: the mailbox disappears from every response and is no longer polled; there is no restore route.

Option list

GET /options returns only id, name and emailAddress of active mailboxes and needs no permission of its own — the scope provides the protection. The for parameter decides which one:

forContains
omitted (default)Mailboxes whose tickets the caller may see — the basis for filtering
createMailboxes they may send from; a subset of the first set
transferall active mailboxes as handover targets — deliberately not limited to your own visibility and therefore gated with tickets.changeMailbox

Any other value for for is refused with 400 instead of silently falling back to the default: a typo in an integration should stand out rather than return a narrower list than intended. Unrestricted mailboxes are always included.

The mailbox object

Identity and paths

FieldMeaning
nameDisplay name, 1–100 characters
emailAddressThe mailbox address; unique system-wide (409 if taken)
protocolIMAP · MS_GRAPH — receive path
receiveConfigConnection details of the receive path, matching the protocol
sendProtocolSMTP · MS_GRAPH — send path
sendConfigConnection details of the send path; an empty object means the mailbox only receives
fromNameSender name; empty ⇒ the application name from the UI settings
replyToAddressReply-to address; empty ⇒ the mailbox address
hasReceiveCredentials · hasSendCredentialsIs a password or client secret stored? The secrets themselves are never read back
signatureIdSignature appended to outgoing mails of this mailbox
checkIntervalMinPoll interval in minutes, 1–60 (default 5)
isActiveIs polled and may send. A deactivated mailbox fetches nothing and refuses sending with 400 SOURCE_MAILBOX_INACTIVE

What becomes of a mail

FieldMeaning
modeTICKET always a ticket · EMAIL_CONVERSATION an email conversation · AUTO ticket if the sender has an account, otherwise a conversation. The response always shows the configured value, never the one resolved per sender
unknownSenderPolicyAUTO_CREATE create a contact · CATCH_ALL attribute everything to one collective account · REJECT reject
catchAllUserIdThe collective account; required with CATCH_ALL (otherwise 400)
defaultCategoryId · defaultGroupId · defaultPriorityDefaults for new tickets. The group must handle tickets (otherwise 400), priority from LOW, MEDIUM, HIGH, URGENT, CRITICAL
subjectPrefixTag in the subject, 1–10 characters; the subject then carries [tag-ticketnumber]
autoReplyEnabledAcknowledgement to the sender
enforceSpf · enforceDkim · enforceDmarcEnforce sender checks; a failed check leads to rejection
bounceDetectionSwitch for handling bounce and out-of-office replies on this mailbox

Post-processing in the mailbox

FieldMeaning
processedActionMARK_READ · MOVE · DELETE — what happens to a processed mail in the mailbox
processedFolderTarget folder for MOVE; required in that case (otherwise 400)
rejectedFolderFolder for rejected mails, default Rejected. Rejected mails are moved, never deleted — without a folder only marking as read remains

Limits per mailbox

FieldDefaultEffect
rateLimitPerMinute60Mails per minute from this mailbox, 1–1000
rateLimitPerSenderPerHour30Mails per sender and hour, 1–1000
autoCreateDailyLimit100Automatically created contacts per day, 1–10000. When the mailbox hits the limit, the creation path answers 429 with a Retry-After until midnight (UTC) — the mail stays open and is processed afterwards

Operating state (read-only)

FieldMeaning
lastCheckedAtLast poll attempt
lastSuccessfulCheckAtLast successful poll; stays put when an error occurs
lastErrorCodeReason of the last error as a code (see below); null means no error. The code also stays set when only the post-processing of a single mail failed
consecutiveErrorsConsecutive errors; 0 after a success
openMailCountBacklog: discovered mails not yet completed
oldestOpenSinceSince when the oldest open mail has been waiting
accessRestrictedIs the access restriction active?

Every poll rewrites these fields — they heal themselves. The system status evaluates the same state: a mailbox without polls, one with errors and one with too old a backlog each report their own reason.

Receive and send configuration

CaseFieldsDefaults
receiveConfig, IMAP host, port, security (none · tls · ssl), username, password, folder, tlsVerify port 993, security ssl, folder INBOX, tlsVerify true
receiveConfig, MS_GRAPH tenantId, clientId, clientSecret, userPrincipal, folder folder inbox
sendConfig, SMTP host, port, security, username (optional), password, tlsVerify port 587, security tls, tlsVerify true
sendConfig, MS_GRAPH tenantId, clientId, clientSecret, userPrincipal —

Password and client secret only go in, never out: they are stored encrypted, and the response only shows whether one is present. If you send no secret when updating, the stored one is kept. tenantId and clientId are Azure identifiers, userPrincipal is an email address.

Folder paths

Receive folder, folder for processed mails and folder for rejected mails are written the same way: as display names, nested levels separated by a slash — Support/Done. That notation applies to both protocols; translating it into the separators and namespaces of the respective server is Eviworx's job. Common names such as INBOX or inbox are recognised regardless of case. The receive folder must exist — it is only looked up, never created; the target folders for processed and rejected mails are created by Eviworx when needed. The folder list shows what the server offers.

Creating and updating

  • Both paths accept known fields only — an unknown field is refused with 400 instead of being silently ignored.
  • The configuration is validated against the chosen protocol: an IMAP mailbox needs IMAP fields, a Graph mailbox needs Graph fields. Error messages name the field path, for instance receiveConfig.host.
  • If the send configuration is missing or empty when creating, the mailbox only receives. There is no silent fallback to a global send path.
  • A partial update changes exactly the fields sent and resets nothing else. Configuration objects may also come partially and are merged with what is stored.
  • Changing the protocol requires sending the matching configuration (otherwise 400) — and it is then not merged with the old one. That closes the gap "new protocol, old credentials".
  • An empty send configuration on update removes sending: the mailbox then only receives.
  • Dependencies are checked against the result, not the request: a collective account must be present even when only the sender policy is changed.

Ability to send

Whether a mailbox can send is decided by one rule for all paths — connection probe, ticket reply and "ticket as email". It follows what sending actually requires:

StateResult
no send configurationRECEIVE_ONLY
SMTP without a user nameable to send — a relay without authentication is a valid setup
SMTP with a user name, password storedable to send
SMTP with a user name, no passwordNO_CREDENTIALS
Microsoft Graph with a client secretable to send
Microsoft Graph without a client secretNO_CREDENTIALS

If a mailbox cannot send, the send paths answer 400 MAILBOX_SEND_NOT_CONFIGURED and name the reason in details.reason — before a message is created, so that no "reply sent" trail exists for a mail that never left. The connection probe deliberately checks only the configuration, not the active switch: a mailbox can be probed before it is activated. On a ticket, sendConfigured in the mailbox reference carries the same value the gate uses — the UI can disable the reply button with it instead of waiting for the error.

Probes: connection and folder list

Both probes run over the same path as production: the same credentials, the same adapter, the same folder resolution. A probe therefore really confirms the production path and not a separate test connection.

POST /api/inbound-mailboxes/:id/test-connection
POST /api/inbound-mailboxes/:id/test-smtp
GET  /api/inbound-mailboxes/:id/folders
{ "connected": true }

{ "data": ["INBOX", "Support/Erledigt", "Rejected"] }
  • A failure is an error, not a response with connected: false: status 400, and the reason of the probe is itself the errorCode (the MAIL_* codes below). details.message carries an English diagnosis for support.
  • If credentials are missing or the mailbox is not set up for sending at all, Eviworx answers 400 right away — without contacting the mail server.
  • If the email service does not answer within 20 seconds, that is an infrastructure case and not a mail error: 503 EMAIL_WORKER_UNAVAILABLE. The probe itself has a tighter deadline so the caller sees the diagnosis rather than the timeout.
  • The folder list carries the edit permission, not view: it supplies data for the edit form.

For global sending without a mailbox context, the two probes of the Settings API apply (/api/settings/email/test-smtp and /test-graph) — same response shape, same error codes.

Access restriction

By default a mailbox is open: whoever may see tickets also sees the tickets of that mailbox. A restricted mailbox inverts this — only people with a grant then see its tickets. This is the way to handle mailboxes such as hr@ or billing@ whose records are not for the whole team.

GrantMeaning
userId · roleId · agentGroupIdExactly one of them per grant: a person, everyone with a role, or an agent group. The UI offers person and role; the group grant is an API-only path
canViewTicketsMay see the tickets of this mailbox
canBeAssignedMay work on them and send from them
  • A second grant to the same target is refused with 409.
  • Revoking a grant that does not exist and revoking a grant belonging to another mailbox answer identically (404 MAILBOX_ACCESS_ENTRY_NOT_FOUND) — the API does not reveal whether a foreign entry exists.
  • The manageAccess permission itself overrides every restriction: whoever holds it sees the tickets of every mailbox and can be assigned to them. That is why it is a critical permission.

Error codes

CodeHTTPWhen
MAILBOX_NOT_FOUND404Unknown or deleted mailbox
MAILBOX_EMAIL_EXISTS409Address already taken; details names the address
MAILBOX_CATCH_ALL_USER_REQUIRED400Sender policy CATCH_ALL without a collective account
MAILBOX_PROCESSED_FOLDER_REQUIRED400Post-processing MOVE without a target folder
AGENT_GROUP_NOT_FOUND404Default group does not exist
GROUP_ENTITY_TYPE_MISMATCH400Default group does not handle tickets
TICKET_CATEGORY_NOT_FOUND404Default category does not exist
MAILBOX_RECEIVE_NOT_CONFIGURED400Receive probe or folder list without stored credentials
MAILBOX_SEND_NOT_CONFIGURED400Mailbox cannot send; details.reason names RECEIVE_ONLY or NO_CREDENTIALS
SOURCE_MAILBOX_INACTIVE400Sending from a deactivated mailbox
MAILBOX_ACCESS_ENTRY_NOT_FOUND404Grant entry does not belong to this mailbox or does not exist
USER_CREATION_LIMIT_EXCEEDED429Daily limit of automatically created contacts reached; Retry-After until midnight (UTC)
EMAIL_WORKER_UNAVAILABLE503The email service did not answer the probe
EMAIL_SYSTEM_DISABLED400Global probes only: the email channel is not enabled
VALIDATION_ERROR400Schema violation; details lists the affected field paths
FORBIDDEN403Permission missing — or an API key calls a user-bound path

Reasons of a mail error

The same seventeen codes appear in two places: as the errorCode of a failed probe and as lastErrorCode on the mailbox. A glance at the list therefore says the same thing as a probe.

CodeMeaning
MAIL_CONNECTION_FAILEDServer unreachable (name or connection)
MAIL_TIMEOUTTimeout exceeded
MAIL_TLS_FAILEDTLS or certificate refused
MAIL_AUTH_FAILEDLogin refused
MAIL_CREDENTIALS_MISSINGNo password or secret stored
MAIL_PERMISSION_DENIEDThe app permission in Microsoft 365 is insufficient
MAIL_MAILBOX_NOT_FOUNDThe given mailbox does not exist there
MAIL_FOLDER_NOT_FOUNDFolder cannot be resolved or created
MAIL_RATE_LIMITEDThe mail server is throttling
MAIL_RECIPIENT_REJECTEDRecipient refused
MAIL_MESSAGE_TOO_LARGEMessage too large for the server
MAIL_MESSAGE_REJECTEDMessage or sender refused
MAIL_CONFIG_UNAVAILABLEMailbox inactive or without the required path
MAIL_QUEUE_UNAVAILABLEThe job could not be queued
MAIL_SEND_FAILEDSending failed without a more specific reason
MAIL_RECEIVE_FAILEDPolling failed without a more specific reason
MAIL_SEND_OUTCOME_UNKNOWNThe attempt broke off — the mail may be out

Audit trail

OperationEntry
CreateCREATE — with receive and send protocol
UpdateUPDATE — old/new for each of the 26 audited single fields; of the configurations only the fact that they were touched is recorded, never their content
DeleteDELETE
Grant / revoke accessMAILBOX_ACCESS_GRANTED · MAILBOX_ACCESS_REVOKED — with target and both flags
Switch restriction on/offMAILBOX_RESTRICTION_ENABLED · MAILBOX_RESTRICTION_DISABLED — only on a real change

Every change to a mailbox reaches the email service immediately: it reloads the mailboxes without waiting for the next poll. A deactivated mailbox therefore stops fetching mails right away.

Related pages

  • Email System — the path of a mail in and out: polling, rejection, backlog, sending and limits in context
  • Tickets API — email thread, replying by mail and the mailbox fields on a ticket
  • Email Signatures API — the signatures a mailbox can append
  • Settings API — the global send path and the channel settings
  • Permissions & RBAC — how mailbox grants interact with ticket visibility