My agentic slop goes here. Not intended for anyone else!

JMAP Library Usage Guide#

Ergonomic API Design#

The JMAP library provides a clean, ergonomic API with short module names and a unified entry point.

Module Structure#

The unified Jmap module combines jmap-core, jmap-mail, and jmap-client into a single, easy-to-use interface.

let id = Jmap.Id.of_string "abc123"
let email_req = Jmap.Email.Query.request_v ~account_id ...
let client = Jmap.Client.create ...

Submodules (For Specialized Use)#

You can also use the submodules directly:

Jmap_core:

Jmap_core.Session.t
Jmap_core.Id.of_string
Jmap_core.Request.make

Jmap_mail:

Jmap_mail.Email.Query.request_v
Jmap_mail.Mailbox.get

Module Hierarchy#

Jmap                           -- Unified interface (START HERE)
├── Client                     -- HTTP client (from jmap-client)
├── Connection                 -- Connection config (from jmap-client)
│
├── Email                      -- Email operations (from jmap-mail)
├── Mailbox                    -- Mailbox operations (from jmap-mail)
├── Thread                     -- Thread operations (from jmap-mail)
├── Identity                   -- Identity management (from jmap-mail)
├── Email_submission           -- Email submission (from jmap-mail)
├── Vacation_response          -- Vacation responses (from jmap-mail)
├── Search_snippet             -- Search snippets (from jmap-mail)
│
├── Session                    -- JMAP Session (from jmap-core)
├── Request                    -- Request building (from jmap-core)
├── Response                   -- Response handling (from jmap-core)
├── Invocation                 -- Method invocations (from jmap-core)
├── Id                         -- JMAP IDs (from jmap-core)
├── Capability                 -- Capabilities (from jmap-core)
├── Filter                     -- Filters (from jmap-core)
├── Comparator                 -- Sorting (from jmap-core)
├── Primitives                 -- Primitive types (from jmap-core)
├── Error                      -- Error handling (from jmap-core)
├── Binary                     -- Upload/download (from jmap-core)
├── Push                       -- Push notifications (from jmap-core)
│
├── Core                       -- Full jmap-core access
└── Mail                       -- Full jmap-mail access

Specialized APIs (For Advanced Use Cases)#

Jmap_core                      -- Core protocol library
├── Session
├── Id
├── Request
├── Response
└── ...

Jmap_mail                      -- Mail extension library
├── Email
├── Mailbox
├── Thread
└── ...

Jmap_client                    -- HTTP client library
└── (unwrapped: Jmap_client, Jmap_connection)

Usage Examples#

Example 1: Creating a Client and Querying Emails#

let conn = Jmap.Connection.bearer_auth ~token:"..." () in
let client = Jmap.Client.create ~sw ~env ~conn ~session_url:"..." () in
let session = Jmap.Client.get_session client in

let query_req = Jmap.Email.Query.request_v
  ~account_id:(Jmap.Id.of_string account_id)
  ~limit:(Jmap.Primitives.UnsignedInt.of_int 10)
  ~sort:[Jmap.Comparator.v ~property:"receivedAt" ~is_ascending:false ()]
  ()
in

let query_args = Jmap.Email.Query.request_to_json query_req in
let invocation = Jmap.Invocation.Invocation {
  method_name = "Email/query";
  arguments = query_args;
  call_id = "q1";
  witness = Jmap.Invocation.Echo;
} in

let req = Jmap.Request.make
  ~using:[Jmap.Capability.core; Jmap.Capability.mail]
  [Jmap.Invocation.Packed invocation]
in

let resp = Jmap.Client.call client req in

Example 2: Using Submodules#

(* Use Jmap_core for core protocol operations *)
let session = Jmap_core.Session.of_json json in
let account_id = Jmap_core.Id.of_string "abc123" in

(* Use Jmap_mail for mail-specific operations *)
let email_req = Jmap_mail.Email.Query.request_v
  ~account_id
  ~limit:(Jmap_core.Primitives.UnsignedInt.of_int 50)
  ()
in

Example 3: Working with IDs and Primitives#

let account_id = Jmap.Id.of_string "abc123" in
let limit = Jmap.Primitives.UnsignedInt.of_int 50 in
let id_str = Jmap.Id.to_string account_id in

Package Structure#

  • jmap - Unified interface (recommended for applications)
  • jmap-core - Core protocol (RFC 8620)
  • jmap-mail - Mail extension (RFC 8621)
  • jmap-client - HTTP client implementation
  • jmap-test - Test suite

Most users should depend on jmap, which pulls in all three libraries. For specialized use cases (e.g., you only need parsing), you can depend on individual packages.

Quick Reference#

Use Case Unified API Submodule API
IDs Jmap.Id Jmap_core.Id
Requests Jmap.Request Jmap_core.Request
Emails Jmap.Email Jmap_mail.Email
Mailboxes Jmap.Mailbox Jmap_mail.Mailbox
Client Jmap.Client Jmap_client

Need Help?#

  • See jmap/lib/jmap.mli for the complete unified API documentation
  • Check jmap/test/test_unified_api.ml for working examples
  • Refer to jmap/test/test_fastmail.ml for real-world usage