Ray
PricingDocsSign inStart free
Browse the docs

Getting started

Ray documentationAuthenticationUsing Ray with AI coding agentsMCP serverTypeScript SDK

Guides

Sending notificationsIdempotencyTemplatesScheduling and test sendsStatus and feedsClick trackingDelivery webhooks

Channels

Email with Amazon SESEmail with SMTPPush notifications with Firebase Cloud MessagingSlack notificationsDiscord notificationsTelegram notificationsSMS with TwilioSMS with sendsms.mnHTTPS webhook channel

Reference

Rate limits and quotasErrors

Getting started

Ray documentationAuthenticationUsing Ray with AI coding agentsMCP serverTypeScript SDK

Guides

Sending notificationsIdempotencyTemplatesScheduling and test sendsStatus and feedsClick trackingDelivery webhooks

Channels

Email with Amazon SESEmail with SMTPPush notifications with Firebase Cloud MessagingSlack notificationsDiscord notificationsTelegram notificationsSMS with TwilioSMS with sendsms.mnHTTPS webhook channel

Reference

Rate limits and quotasErrors

Getting started

Using Ray with AI coding agents

Integrate Ray with Claude Code, Cursor or Codex using the MCP server, the TypeScript SDK, ray-skills, llms.txt, markdown docs and a copy-paste prompt.

View as Markdownllms.txtAPI reference

Ray is designed to be wired in by AI coding agents such as Claude Code, Cursor and Codex. Everything an agent needs is machine-readable or callable: an MCP server that exposes the API as tools, a typed SDK, skills, these docs as markdown, and the OpenAPI contract.

Recommended setup

Use these in order. Each step is optional, but the earlier ones save the agent the most guessing.

  1. MCP server. Connect https://ray-api.gege.mn/mcp to the agent. It can then look up your channels and their recipient schemas, create and test templates, send, check delivery and read the docs itself, instead of asking you for ids. In Claude Code: claude mcp add --transport http ray https://ray-api.gege.mn/mcp --header "Authorization: Bearer $RAY_API_KEY".
  2. TypeScript SDK. Have the agent write application code against @gege-mn/ray (npm install @gege-mn/ray) rather than hand-rolled fetch calls. It comes with types, a RayError class, an idempotencyKey option on sends and a webhook signature verifier, so the agent has less to get wrong.
  3. ray-skills. Skills that teach an agent Ray's integration patterns and email template design. Install with npx skills add gege-mn/ray-skills, or in Claude Code with /plugin marketplace add gege-mn/ray-skills then /plugin install ray@ray-skills.
  4. Docs as markdown. https://ray.gege.mn/llms.txt indexes every page; append .md to any docs URL for that page alone.
  5. OpenAPI 3.1 spec. The exact request and response schemas, for agents working in another language or generating their own client.

Machine-readable resources

Resource URL Use it for
MCP server https://ray-api.gege.mn/mcp Ray's API as MCP tools, authenticated with your API key. Setup for each client: MCP server.
Local MCP package npx -y @gege-mn/ray-mcp The same tools as a stdio server, for clients that can't send a header to a remote server. Source: https://github.com/gege-mn/ray-mcp.
TypeScript SDK npm install @gege-mn/ray Typed client for Node.js, Bun, Deno and edge runtimes. Docs: TypeScript SDK. Source: https://github.com/gege-mn/ray-node.
ray-skills https://github.com/gege-mn/ray-skills Agent skills for wiring Ray into a project and designing email templates.
llms.txt https://ray.gege.mn/llms.txt Index of all doc pages with one-line descriptions.
llms-full.txt https://ray.gege.mn/llms-full.txt All doc pages concatenated into one file.
Raw markdown pages https://ray.gege.mn/docs/<page>.md Any single page as plain markdown, for example https://ray.gege.mn/docs/sending.md or https://ray.gege.mn/docs/channels/telegram.md.
OpenAPI 3.1 spec https://ray-api.gege.mn/openapi.json The exact request and response schemas, generated from the same schemas the API validates with.
API reference https://ray-api.gege.mn/docs Interactive reference (Scalar) for humans.
Channel discovery GET https://ray-api.gege.mn/channels The workspace's channel configs with their channelConfigId, template kind and the JSON Schema of the recipient object. Also the list_channels MCP tool and ray.channels.list() in the SDK.

The .md trick: every docs URL works with .md appended and returns the page without navigation or styling. When an agent needs one topic, give it that URL instead of the HTML page or the full bundle. The MCP read_docs tool returns the same markdown.

Set up access

  1. Create an API key in the dashboard (https://ray.gege.mn, API keys). An agent that creates templates or sends needs the write scope. For exploring and debugging, a key with only read is safer: it can't send anything. Consider dedicated keys for development so you can revoke them independently.
  2. Put it in your environment, not in code:
# .env (keep out of version control)
RAY_API_KEY=ck_live_...
  1. Configure at least one channel in the dashboard under Channels. Channel credentials can't be created through the API, so the agent works with configs you have already set up and finds them with GET /channels.

Let the agent verify access before writing code, with the whoami and list_channels MCP tools or with curl:

curl https://ray-api.gege.mn/me -H "Authorization: Bearer $RAY_API_KEY"
curl https://ray-api.gege.mn/channels -H "Authorization: Bearer $RAY_API_KEY"

Point your agent at the docs

  • Claude Code: add the MCP server, install ray-skills, and add a line to your project's CLAUDE.md such as Ray notification API: use the @gege-mn/ray SDK. Docs: https://ray.gege.mn/llms.txt (append .md to any docs URL for raw markdown). API spec: https://ray-api.gege.mn/openapi.json.
  • Cursor: add the MCP server, and add https://ray.gege.mn/llms-full.txt as a documentation source or reference the .md URL of the page you are working on in the chat.
  • Codex: add the MCP server and the same line to AGENTS.md.
  • Other agents: see MCP server, or paste the prompt below.

Copy-paste prompt

Integrate the Ray notification API into this project.

Ray is a notification delivery API (not the Ray distributed computing framework).
- MCP server: https://ray-api.gege.mn/mcp (tools list_channels, send_notification, get_send_status, read_docs, ...). If it is connected, use it to inspect the workspace instead of guessing ids.
- TypeScript SDK: npm install @gege-mn/ray (docs: https://ray.gege.mn/docs/sdk.md). Use it in TypeScript/JavaScript projects instead of raw fetch.
- Docs index: https://ray.gege.mn/llms.txt
- Any docs page as markdown: append .md, e.g. https://ray.gege.mn/docs/sending.md
- OpenAPI spec (source of truth for request/response shapes): https://ray-api.gege.mn/openapi.json
- API base URL: https://ray-api.gege.mn
- Auth: header "Authorization: Bearer <key>", key read from the RAY_API_KEY environment variable. Never hardcode it or expose it to client-side code.

Requirements:
1. Find the channelConfigId, the channel's templateKind and the exact recipient JSON Schema first (list_channels tool, ray.channels.list(), or GET /channels). Do not guess recipient shapes.
2. Create a server-side helper that sends with ray.send(...) (or POST /send) and returns the sendId from the 202 response.
3. Pass an idempotency key derived from the business event (for example "order-shipped-<orderId>") on every send: the idempotencyKey option in the SDK, or the Idempotency-Key header over HTTP, so retries never double-send.
4. Without the SDK, retry only on 429 (honor Retry-After), 5xx and network errors, always with the same Idempotency-Key. Treat 400 and 404 as bugs and surface the error code and message (RayError in the SDK).
5. For reusable content, create a template (publish: true) and send with templateId; otherwise send inline content. Pass every required param. Try templates with a test send to my own address before real sends.
6. If the app shows in-app notifications, pass externalUserId and showInFeed: true (or feed) on sends, and proxy the feed (ray.notifications.list or GET /notifications?externalUserId=...) through the backend.
7. If handling delivery webhooks, verify X-Ray-Signature against the raw request body before parsing: verifyWebhookSignature from @gege-mn/ray, or HMAC-SHA256 of "<t>.<raw body>" with a 5 minute tolerance.

The notification to implement: <describe it: trigger, channel, recipient, content>.

Tips for agents

  • Read the relevant page before writing code: Sending, Templates, the channel guide for the channel in use, and Errors.
  • recipientSchema from GET /channels is authoritative for the recipient object. The template kind (templateKind) tells you which content shape to use.
  • Validation error messages name the field that failed (recipient: ..., content: subject: ..., missing required params: name), so agents can fix requests from the response alone.
  • POST /send returning 202 means accepted, not delivered. Check GET /sends/{sendId} (the get_send_status tool) in tests or subscribe to webhooks in production.
  • Use POST /templates/{id}/test-send (the test_send_template tool) to exercise a template against a real inbox without creating feed entries, firing webhooks or using quota.
PreviousAuthenticationNextMCP server

On this page

  • Recommended setup
  • Machine-readable resources
  • Set up access
  • Point your agent at the docs
  • Copy-paste prompt
  • Tips for agents
Ray

Notification delivery for teams that already have providers.

Product

PricingDocsAPI referenceMCP serverTypeScript SDKAgent skillsllms.txt

Legal

TermsPrivacyRefunds

Contact

[email protected]

© 2026 L’Atelier Gege LLC