Linq Messaging

Send and receive iMessage, RCS, and SMS in Convex actions with signed webhook verification, idempotent sends, and zero component-owned storage.

Installation

npm install @linqapp/convex

About Linq Messaging

Linq Messaging connects your Convex backend to iMessage, RCS, and SMS through the Linq Partner API. Verify inbound webhooks, reply in an existing conversation, or start a conversation with an explicit sender line or automatic line selection. Read receipts, typing indicators, and delivery events use the same integration.

The component runs in Convex’s default runtime and does not create message tables or scheduled jobs. Your app controls its own conversation state, agent behavior, and retention. A complete example covers installation, webhook registration, replies, and outbound sends.

Benefits

Use cases

how to receive iMessage webhooks in Convex

The @linqapp/convex component registers an HTTP route at /linq/webhook that verifies Standard Webhooks signatures and calls your configured onMessage action. You define the handler as an internalAction using the onMessageArgs schema, and the component passes verified message fields like chatId, from, text, and messageId directly to your handler.

how to send SMS or iMessage from a Convex action

Call linq.sendMessage from any Convex action with a chatId or a to phone number array, message text, and a stable idempotencyKey. The component retries on network errors and transient failures using the same key, so duplicate calls with the same key will not send the message twice.

how to build an AI SMS or iMessage bot with Convex

Configure the Linq component with an onMessage handler action that receives inbound messages, calls your LLM, and replies using linq.sendMessage with an idempotencyKey derived from the inbound messageId. For slow LLM calls that exceed the 10-second webhook deadline, use ctx.scheduler.runAfter to defer the work and pass message identifiers rather than full text on zero-retention lines.

idempotent message sending Convex webhook redelivery

The @linqapp/convex component lets you supply a stable idempotencyKey to linq.sendMessage. Linq enforces that each key is sent at most once, so if a webhook is redelivered and your handler runs again, the same key prevents a duplicate outbound message. If you omit the key, the component generates a random one that only protects the in-call retries of that single invocation.

Frequently asked questions

Does the Linq Convex component store message content in any database tables?

No. The @linqapp/convex component declares no database tables and schedules no background jobs. Inbound message data exists only in memory during the webhook request and in the arguments of your onMessage action. Any persistence is entirely your responsibility in your own application tables.

What happens if my Linq webhook handler throws an error or times out?

If your onMessage handler throws or the response is not returned within 10 seconds, the component returns HTTP 500 and Linq redelivers the event, retrying for up to 30 minutes. You should make all handler side effects safe to repeat and derive idempotencyKey from the inbound messageId so that a redelivery does not send a duplicate reply.

Does @linqapp/convex require a Node.js runtime?

No. The Linq Convex component runs in Convex's default runtime and does not require the 'use node' directive on any of its functions.

How do I handle slow AI agent work that takes longer than 10 seconds inside a Linq webhook?

Use ctx.scheduler.runAfter inside your onMessage handler to schedule the slow work as a separate Convex action. This returns control to the webhook immediately. On zero-day-retention lines, pass only message identifiers to the scheduled action rather than full message text, since scheduled job arguments persist in your Convex deployment for 7 days after the job finishes.

How does Linq webhook signature verification work in this component?

The @linqapp/convex component verifies Standard Webhooks signatures on every inbound request using the LINQ_WEBHOOK_SECRET environment variable before your handler is called. An invalid or missing signature returns HTTP 401 and no handler runs. A missing or misconfigured local secret returns HTTP 500 so Linq can redeliver after you fix the deployment configuration.

Links

Components

Open-source building blocks for your Convex app

Browse components in this category.

Loading components