2025-08-02 16:53:51 +02:00
2025-08-06 18:03:22 +02:00
2025-08-02 16:53:51 +02:00
2025-08-08 00:28:05 +02:00
2025-08-02 16:53:51 +02:00
2025-08-02 16:53:51 +02:00
2025-08-08 23:53:11 +02:00

Casey

Casey is a fully opensource headless support case management service. Every interaction with Casey is done either via HTTP or e-mail. To open a case, ask the user for useful information before sending a HTTP request to create the case. This will send e-mails to the poster, as well as a configurable number of team members, and from this point on the entire communication can be performed in an official but slightly anonymized fashion.

Users will only exchange messages with one single address; your support address. This is true no matter how many participants a case has. That means there is no risk of internal e-mail addresses leaking (unless explicitly quoted in the messages exchanged).

Installation

With docker:

$ docker run --name casey dev.noccylabs.info/casey/casey:latest

With docker-compose:

services:
  casey:
    image: dev.noccylabs.info/casey/casey:latest

Interacting

Directly

Step 1: Create your team

POST /api/casey/v1/persons
Content-Type: application/json

{
    "name": "Ben Foo",
    "email": "ben@domain.tld",
    "team": true
}

Step 2: Create a case

POST /api/casey/v1/cases
Content-Type: application/json

{
    "creator": {
        "name": "Some User",
        "email": "some.user@other.tld"
    },
    "subject": "I found a bug",
    "message": "There is a bug over there!"
}

You can include additional data for indexing and analysis: category is a string categorizing the case (ex. support, questions, warranty), tags is an array of tags to attach to the case, and if that's not enough, you can use available keys in the meta object as long as they will not collide with any internal meta keys. It is recommended that you prefix your keys, f.ex. instead of orderNumber use myPlatformOrderNumber.

Post a message to the case

While this is normally done by sending an e-mail message including the case reference, you can also post messages via the HTTP API.

The case UUID for {uuid} can be found in the create case response.

POST /api/casey/v1/case/{uuid}/messages
Content-Type: application/json

{ 
    "from": "ben@domain.tld",
    "message": "Hello Some User,\n\nWe are excited to hear about the bug. Can you tell us more?"
}

Retrieve the case

GET /api/casey/v1/case/{uuid}

This will retrieve the full case, suitable for presentation on a webpage.

Note: This response may contain e-mail addresses and other private information of the participants, and should never be passed directly to the user's browser.

Configuration

Configuration Keys

caseConfirmation

bool: If this is true, a case will be put into a pending state when it is created, until the creator confirms the case by clicking on a link and only then will team members be notified about a new case. If it is false, the case will be automatically confirmed and team members will be notified immediately.

Note: Since Casey is API only, your front-end will have to do some work to extract the confirmation codes, and also provide some hints to Casey on how to put the confirmation links together.

caseCloseIdle

int|string: The maximum time a case can be idle before it is automatically closed by the system. This should probably be a duration string, such as 30d

caseCanReopen

bool: If true, closed cases can be reopened by sending a message to the case via HTTP or mail.

caseSendInitial

bool: If this is true, a copy of the initial message will be sent to the creator. If false, the creator will not receive the initial message, but still receive all replies.

caseSendCopy

bool: If this is true, the posting participant will receive a copy of their message as they post to a case.

caseConfirmUrl

string: String used to generate confirmation URLs. The placeholder %code% will be replaced with the confirmation code.

teamInviteReminder

int|string:

teamInviteCount

int:

mailEnable

bool: Set to false to disable all the mail functionality, and only use HTTP for all interactions with Casey.

mailSubjectFormat

string: How subject lines will be formatted; the placeholders %reference%, %prefix% and %subject% will be replaced with the appropraite values.

mailSubjectPrefix

string: Value to put in the %prefix% placeholder.

mailSyncTimer

int: Seconds between synchronizing incoming and outgoing mail

mailAddress

string: The e-mail address to send and receive messages from

mainDomain

string: The base domain to use for message IDs. If null, domain of mailAddress is used.

smtpAdapter smtpServer smtpPort smtpUsername smtpPassword smtpEncryption

SMTP configuration

imapAdapter imapServer imapPort imapUsername imapPassword imapEncryption

IMAP configuration

Setting a config file

With docker-compose:

  environment:
    CASEY_CONFIG_FILE=/path/to/config.json

Running native:

$ caseyd --config /path/to/config.json

Runtime configuration

Get configuration:

GET /api/casey/v1/config

Update one or more keys:

POST /api/casey/v1/config
Content-Type: application/json

[
    { "mailSyncTimer": 120 }
]

Commit the keys to primary config file:

POST /api/casey/v1/config/commit
Description
Languages
PHP 90.7%
Twig 7.2%
CSS 1.4%
Makefile 0.4%
Dockerfile 0.3%