---
name: pp-nylas
description: "Every Nylas API, plus a local SQLite mirror, cross-grant search, and confirm-by-hash sending no other Nylas tool has. Trigger phrases: `search my Nylas inbox across all grants`, `what changed in Nylas in the last 2 hours`, `first-response time on my Nylas threads`, `replay a Nylas webhook locally`, `preview a Nylas send before it goes out`, `use nylas`, `run nylas-pp-cli`."
author: "Nathan Kettles"
license: "Apache-2.0"
argument-hint: "<command> [args] | install cli|mcp"
allowed-tools: "Read Bash"
metadata:
  openclaw:
    requires:
      bins:
        - nylas-pp-cli
---
<!-- GENERATED FILE — DO NOT EDIT.
     This file is a verbatim mirror of library/productivity/nylas/SKILL.md,
     regenerated post-merge by tools/generate-skills/. Hand-edits here are
     silently overwritten on the next regen. Edit the library/ source instead.
     See the repository agent guide, section "Generated artifacts: registry.json, cli-skills/". -->

# Nylas — Printing Press CLI

## Prerequisites: Install the CLI

This skill drives the `nylas-pp-cli` binary. **You must verify the CLI is installed before invoking any command from this skill.** If it is missing, install it first:

1. Install via the Printing Press installer. It defaults binaries to `$HOME/.local/bin` on macOS/Linux and `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows:
   ```bash
   npx -y @mvanhorn/printing-press-library install nylas --cli-only
   ```
2. Verify: `nylas-pp-cli --version`
3. Ensure the reported install directory is on `$PATH` for the agent/runtime that will invoke this skill.

If the `npx` install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.6 or newer):

```bash
go install github.com/mvanhorn/printing-press-library/library/productivity/nylas/cmd/nylas-pp-cli@latest
```

If `--version` reports "command not found" after install, the runtime cannot see the binary directory on `$PATH`. Do not proceed with skill commands until verification succeeds.

## When to Use This CLI

Reach for nylas-pp-cli when you need to query Nylas data across multiple grants, run repeat 'what changed since' polls cheaply, compose SQL over messages and events, or sample the wire payload of a send before it goes out. For pure single-call API parity with the official SDK, the official nylas-cli is also a fine choice.

## Unique Capabilities

These capabilities aren't available in any other tool for this API.

### Local state that compounds
- **`sync`** — Pull messages, events, threads, and contacts for one or all grants into a local SQLite mirror with per-(grant, resource) cursors so re-runs are incremental.

  _Reach for this when an agent needs to answer questions repeatedly without burning rate-limit on every call._

  ```bash
  nylas-pp-cli sync --resources messages,events --since 24h --agent
  ```
- **`since`** — Query the local mirror for resources changed in the last N (e.g. 2h, 24h) across all grants in one shot.

  _Cheapest path to 'what changed' polling without API round-trips._

  ```bash
  nylas-pp-cli since 2h --resource messages --agent --select id,subject,from,grant_id
  ```
- **`search`** — FTS5 search over messages, threads, events, and contacts spanning every connected grant in a single query (use --type to filter by resource).

  _Use this to find references anywhere across a tenant without N separate searches._

  ```bash
  nylas-pp-cli search "invoice overdue" --type messages --limit 50 --agent
  ```
- **`export`** — Stream the local mirror (or a filtered slice) to NDJSON for downstream analytics tools like DuckDB or notebooks.

  _Pipe Nylas data into duckdb or a notebook in one command._

  ```bash
  nylas-pp-cli export --resource messages --since 90d --format ndjson
  ```

### Cross-grant analytics
- **`gravity`** — Rank contacts by cross-grant interaction weight (sent + received + meeting-attended), unified by email address.

  _Surfaces 'who actually matters to this tenant' in one call for CRM hygiene or agent prioritisation._

  ```bash
  nylas-pp-cli gravity --top 25 --since 90d --agent
  ```
- **`response-time`** — Compute median and p90 first-response latency on threads where the grant-holder replied, sliced by grant or counterparty domain.

  _An SLA dashboard in one command, impossible against the live API in under five minutes of round-trips._

  ```bash
  nylas-pp-cli response-time --group-by domain --since 30d --agent
  ```

### Reliability & safety
- **`webhook-replay`** — Re-fire any past webhook delivery from the local store into a local handler URL, optionally filtered by trigger or grant.

  _Reproduce a production webhook bug in seconds without waiting for the next event to fire._

  ```bash
  nylas-pp-cli webhook-replay --since 24h --trigger message.created --to http://localhost:3000/hook
  ```
- **`grants messages send`** — Use --dry-run to print the exact wire payload for any grants messages send call; pair with --yes (or --agent) to bypass interactive confirmation only when you've reviewed the preview.

  _Every destructive action is reviewable; an agent can show the payload before sending._

  ```bash
  nylas-pp-cli grants messages send 550e8400-e29b-41d4-a716-446655440000 --to PII_EMAIL_EXAMPLE --body 'note' --dry-run
nylas-pp-cli grants messages send 550e8400-e29b-41d4-a716-446655440000 --to PII_EMAIL_EXAMPLE --body 'note' --yes
  ```
- **`grants messages send`** — Pass the global --idempotent flag so an already-existing create result is treated as a successful no-op, making the send safe to retry inside an agent loop.

  _Safe to call inside an agent retry loop._

  ```bash
  nylas-pp-cli grants messages send 550e8400-e29b-41d4-a716-446655440000 --to PII_EMAIL_EXAMPLE --body 'note' --idempotent --agent
  ```
- **`grants doctor`** — Health-check every grant: token expiry, missing scopes for advertised features, recent webhook failures, sync lag.

  _Tells you which mailboxes are quietly broken before users notice._

  ```bash
  nylas-pp-cli grants doctor --agent
  ```

### Agent-native plumbing
- **`sql`** — Read-only SQL query against the local mirror with --json output.

  _Anything we forgot to expose as a verb, an LLM can still answer through SQL._

  ```bash
  nylas-pp-cli sql "SELECT from_addr, COUNT(*) FROM messages GROUP BY 1 ORDER BY 2 DESC LIMIT 20" --agent
  ```
- **`--agent (global flag)`** — Single flag that forces --json --compact --no-input --no-color --yes defaults so any read command is LLM-safe in one switch.

  _One flag flips the entire CLI into LLM-safe mode; eliminates a class of prompt-eats-stdin bugs._

  ```bash
  nylas-pp-cli grants get-all --agent --limit 10
  ```

## Command Reference

**admin** — Manage admin

- `nylas-pp-cli admin create-api-key` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage API Keys endpoints, you need to <a...
- `nylas-pp-cli admin create-domain` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage Domains endpoints, you need a <a...
- `nylas-pp-cli admin delete-api-key` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage API Keys endpoints, you need to <a...
- `nylas-pp-cli admin delete-domain` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage Domains endpoints, you need a <a...
- `nylas-pp-cli admin get-api-key` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage API Keys endpoints, you need to <a...
- `nylas-pp-cli admin get-api-keys` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage API Keys endpoints, you need to <a...
- `nylas-pp-cli admin get-domain` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage Domains endpoints, you need a <a...
- `nylas-pp-cli admin get-domain-info` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage Domains endpoints, you need a <a...
- `nylas-pp-cli admin list-domains` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage Domains endpoints, you need a <a...
- `nylas-pp-cli admin update-domain` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage Domains endpoints, you need a <a...
- `nylas-pp-cli admin verify-domain` — <div id='admonition-warning'>⚠️ <b>Before you can use the Manage Domains endpoints, you need a <a...

**applications** — In the context of the Nylas APIs, an "application" is the object record of your Nylas application.

<div id="admonition-info">🔍 <b>The term "application" can refer to any of three concepts</b>: your Nylas application, the project you're building ("your application" or "your app"), and applications that you use to connect to service providers ("provider auth applications"). We try to be specific in this documentation to avoid confusion. The API endpoints described here are for working with your Nylas application, specifically.</div>

The Nylas application is the central resource for your Nylas implementation. It collects the [connectors](/docs/reference/api/connectors-integrations/) that you use to store information about third party services that your application connects to, and stores the [grants](/docs/reference/api/manage-grants/) that you create when using connectors.

Nylas applications also allow you to define your specific branding, change the look and feel of the Nylas Hosted authentication flow, and list your application's callback URIs.

## Application callback URIs

Your Nylas application includes a list of allowed callback URIs. These are known URIs that Nylas can direct users to after authentication. You need to define at least _one_ callback URI so your users can complete the auth flow.

You must include any callback URIs you plan to use in this list. If an auth payload includes a callback URI that isn't on the list, the whole authentication flow fails.

## Application limitations

<div id="admonition-warning">⚠️ <b>You can create, edit, and delete applications from the Nylas Dashboard</b>. You <i>cannot</i> create, edit, or delete them using the Nylas APIs.</div>

Keep the following limitations in mind as you work with Nylas applications:

- Applications are the central resource that stores other Nylas resources. You _must_ create an application before you can create any other parts of your Nylas implementation.
- Applications can be associated with only one project at a time. While your project can have more than one Nylas application to provide different authentication experiences, you cannot share applications, connectors, or grants between more than one project.
- Applications cannot be nested, and cannot be set up with parent-child relationships.
- Your application must have _at least one_ callback URI, or else it cannot finish the authentication flow, which means it cannot create grants. Nylas requires grants to access user data.
  - In an ideal scenario, your application will have multiple callback URIs defined.

- `nylas-pp-cli applications add-callback-uri` — Adds a callback URI to the specified Nylas application. Nylas uses callback URIs to redirect users to your project...
- `nylas-pp-cli applications delete-callback-uri` — Deletes the specified callback URI.
- `nylas-pp-cli applications get` — Gets the application object
- `nylas-pp-cli applications get-all-callback-uris` — Returns a list of callback URIs for the specified Nylas application.
- `nylas-pp-cli applications get-callback-uri` — Returns the specified callback URI.
- `nylas-pp-cli applications update` — Updates a Nylas application using the client ID associated with the specified API key. <div...
- `nylas-pp-cli applications update-callback-uri` — Updates the specified callback URI. If you don't define the `platform`, Nylas doesn't modify the existing settings....

**calendars** — The Nylas Calendar API allows you to create and manage calendars, and access the events they contain. Nylas uses the same commands to manage calendars across providers, and you can refer to specific calendars using the provider's `calendar_id`.

Depending on the provider, a calendar might be accessed by only one person, or shared among several users. Some common calendars might include Personal, Work, or Shared calendars.

A calendar might contain overlapping events or conflicting schedules. You can use the [Get Availability endpoint](/docs/reference/api/calendar/post-availability/) to find the best time for an event by identifying time periods that have no conflicting events among all participants.

## Find a calendar ID

You must specify a `calendar_id` in all calls you make to the Nylas Calendar API. You can use `primary` to specify the primary calendar associated with a grant, or you can look up the ID of the calendar that you want to work with and use that.

For virtual calendars, the `primary` calendar is the first created for a virtual account. You _cannot_ delete a virtual calendar that's designated as `primary`.

For iCloud, there is no `primary` calendar.

## Free/Busy information

The [Get Free/Busy Schedule endpoint](/docs/reference/api/calendar/post-calendars-free-busy/) is available for all providers, including Virtual Calendars, except for iCloud.

The [Get Availability endpoint](/docs/reference/api/calendar/post-availability/) doesn't support the `free_busy` object.

## Virtual calendars

Nylas allows you to create virtual calendars for users and resources that might not have calendars on your providers (for example, external contractors or meeting rooms). You can use the Nylas Calendar and Events APIs with the virtual accounts that power virtual calendars, just like you would any other account. Virtual accounts don't provide email or contacts features, so you can't use them with the Email or Contacts APIs.

For more information, see [Using virtual calendars](/docs/v3/calendar/virtual-calendars/).

## Metadata on calendars

You can add metadata to new and existing calendars by including the `metadata` sub-object in your `POST`, `PUT`, or `PATCH` request. For more information, see the [Metadata documentation](/docs/dev-guide/metadata/).

## Calendar scopes

The table below lists the Calendar endpoints and which scopes they require. The table shortens the full scope URI for space reasons, so add the prefix for the provider when requesting scopes.

The ☑️ in each column indicates the most restrictive scope you can request for each provider and still use that API. More permissive scopes appear under the minimum option. If you're already using one of the permissive scopes, you don't need to add the more restrictive scope.

| Endpoint                                                                                                                               | Google Scopes</br>`https://www.googleapis.com/auth/...` | Microsoft Scopes</br>`https://graph.microsoft.com/...` |
| :------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------ | :----------------------------------------------------- |
| **GET** `/calendars`</br>**GET** `/calendars/<CALENDAR_ID>`</br>**POST** `/calendars/free-busy`</br>**POST** `/calendars/availability` | `/calendar.readonly` ☑️</br>`/calendar`                 | `Calendars.Read` ☑️</br>`Calendars.ReadWrite`          |
| **POST** `/calendars`</br>**PUT** `/calendars/<CALENDAR_ID>`</br>**DELETE** `/calendars/<CALENDAR_ID>`                                 | `/calendar` ☑️                                          | `Calendars.ReadWrite` ☑️                               |

For more information about scopes, see [Using scopes to request user data](/docs/dev-guide/scopes/).

## Calendar activity notifications

You can subscribe to the following triggers so Nylas notifies you about changes to your users' calendar data:

- `calendar.created`
- `calendar.updated`
- `calendar.deleted`

For more information, see the [Calendar webhook notification schemas](/docs/reference/notifications/#calendar-notifications).

## Microsoft event considerations

Microsoft Outlook events are often shared across all calendars in a user's account. If the user creates an event on one of their calendars, you can retrieve it using another calendar ID from their grant.

- `nylas-pp-cli calendars` — Returns availability information for the specified user or group of users. All participants' email addresses must be...

**channels** — Manage channels

- `nylas-pp-cli channels create-pubsub` — Create a Pub/Sub channel in the specified application.
- `nylas-pp-cli channels create-sns` — Create an Amazon SNS notification channel in the specified application. The `topic` must be a valid Amazon SNS topic...
- `nylas-pp-cli channels delete-pubsub-by-id` — Delete a specific Pub/Sub channel from a specific Nylas application.
- `nylas-pp-cli channels delete-sns-by-id` — Delete a specific Amazon SNS notification channel from a specific Nylas application.
- `nylas-pp-cli channels get-pubsub` — Get the Pub/Sub channels for an application.
- `nylas-pp-cli channels get-pubsub-by-id` — Get a specific Pub/Sub channel from a specific Nylas application.
- `nylas-pp-cli channels get-sns` — Get the Amazon SNS notification channels for an application.
- `nylas-pp-cli channels get-sns-by-id` — Get a specific Amazon SNS notification channel from a specific Nylas application.
- `nylas-pp-cli channels put-pubsub-by-id` — Updates the specified Pub/Sub channel. When you make a `PUT` request, Nylas replaces all data in the nested object...
- `nylas-pp-cli channels put-sns-by-id` — Updates the specified Amazon SNS notification channel. When you make a `PUT` request, Nylas replaces all data in the...

**connect** — Manage connect

- `nylas-pp-cli connect byo-auth` — Manually creates a grant using the Bring Your Own (BYO) Authentication flow. If you're handling the OAuth flow in...
- `nylas-pp-cli connect exchange-oauth2-token` — The standard OAuth token endpoint for Hosted Authentication. This endpoint doesn't require authentication, as it is...
- `nylas-pp-cli connect get-oauth2-flow` — The initial OAuth 2.0 authorization request. Use this endpoint with the required query parameters to start the OAuth...
- `nylas-pp-cli connect info-oauth2-token` — Get info about a specific token based on the identifier you include. Use _either_ the ID Token or Access...
- `nylas-pp-cli connect revoke-oauth2-token-and-grant` — Revokes the specified OAuth access token. When you revoke the token, Nylas _doesn't_ revoke the grant or the...

**connectors** — Manage connectors

- `nylas-pp-cli connectors create` — Create a connector in your Nylas application. Connectors are how your Nylas application stores information it needs...
- `nylas-pp-cli connectors delete-by-provider` — Delete the existing connector for the provider you specify.
- `nylas-pp-cli connectors get-all` — List the connectors in your Nylas application.
- `nylas-pp-cli connectors get-by-provider` — Returns a connector for the specified provider.
- `nylas-pp-cli connectors update-by-provider` — Update the connector for the specified provider. When you make a `PATCH` request, Nylas replaces all data in the...

**domains** — Manage domains


**grants** — Manage grants

- `nylas-pp-cli grants delete-by-id` — Delete an existing grant by ID. You cannot re-authenticate the deleted grant. If you try to re-authenticate it,...
- `nylas-pp-cli grants get-all` — Returns all grants in your Nylas application.
- `nylas-pp-cli grants get-by-access-token` — Gets a grant using current access token
- `nylas-pp-cli grants get-by-id` — Gets a grant with the provided ID. If the grant's `grant_status` is `invalid`, the grant has expired and needs to be...
- `nylas-pp-cli grants patch-by-id` — Updates the specified grant's stored settings or scope metadata. **Common use cases:** - **Rotate a refresh token**...

**lists** — The Lists endpoints let you manage typed collections of values (email addresses, domains, or top-level domains) that can be referenced by Rules using the `in_list` condition operator. Lis