General Usage
What is a 'line' in Tuco AI?
What is a 'line' in Tuco AI?
- It represents a specific phone/email/iMessage identity.
- Each line has:
- Daily new conversations and total message limits.
- Health status (healthy/unhealthy).
- Usage counters for the current day.
fromLineId.Use
/api/lines/by-user to list and filter active, healthy lines.What's the difference between Quick Send and sending to leads?
What's the difference between Quick Send and sending to leads?
- One-off message, no need to create a lead.
- Ideal for testing or ad-hoc outreach.
- Can still use availability checks and scheduling.
- Uses leads stored in Tuco.
- Integrated with availability, campaigns, and reporting.
- Best for repeatable, large-scale outreach.
How does Tuco choose between iMessage, SMS, and email?
How does Tuco choose between iMessage, SMS, and email?
- Availability checks to determine iMessage support per address.
- Message type (
imessage,sms,email) you specify. - Fallback rules when iMessage is unavailable.
/features/check-availability and /features/failures-and-fallbacks for the complete decision logic.Availability & Fallbacks
How does iMessage availability checking work?
How does iMessage availability checking work?
- Primary phone
- Primary email
- Alt phones (1–3)
- Alt emails (1–3)
- The lead is marked as “unavailable” for iMessage.
- Campaigns and Quick Send can fallback to SMS/email depending on your settings.
What happens if a recipient does not have iMessage?
What happens if a recipient does not have iMessage?
- The worker emits a
message.fallbackwebhook with:event: "message.fallback"- A
reasonstring describing why iMessage is unavailable. checkedAddressesfor debugging.
- Your app can then:
- Route the message via SMS or email.
- Flag the lead’s iMessage availability as unavailable.
Do availability checks ever mark a message as 'failed'?
Do availability checks ever mark a message as 'failed'?
- Messages are typically:
- Sent via iMessage if available.
- Marked as
fallbackwhen iMessage is unavailable.
- Availability logic itself does not cause messages to be marked
failed; health and provider errors do.
Campaigns & Workers
How often are campaigns processed?
How often are campaigns processed?
- A job runs roughly every few minutes (e.g. ~7 minutes).
- Each run:
- Evaluates all active campaigns.
- Applies line limits, time windows, and gaps.
- Moves eligible messages from
queuedtopending.
pending → sent) happens in separate worker jobs that run continuously.Why are many campaign messages stuck in 'queued'?
Why are many campaign messages stuck in 'queued'?
- Daily limits reached for one or more lines:
dailyNewConversationsLimitexceeded.dailyTotalMessagesLimitexceeded.
- Your configured time window has not opened yet.
- The current day is not in allowed days of week.
- Gap enforcement between contacts on a line has not been satisfied.
queued and will be retried in future worker runs.Can a queued message become 'failed' just because limits are reached?
Can a queued message become 'failed' just because limits are reached?
- Daily new conversation limits,
- Daily total message limits,
- Time windows,
- Allowed days of week, or
- Gap constraints
failed. Instead, the message remains queued until conditions allow it to be processed.When do campaigns complete?
When do campaigns complete?
sentdeliveredfailedcancelled
checkAndCompleteCampaign) to:- Scan message states.
- Flip campaign status to
completedwhen noqueuedorpendingmessages remain.
Line Health & Failures
What happens if a line goes offline during a campaign?
What happens if a line goes offline during a campaign?
-
For a lead that already received prior messages from that line:
- Remaining queued messages for that lead on the failed line are marked
failed. - Reason: “Line became inactive after previous messages were sent”.
- We do not reassign to a different line to preserve conversation continuity.
- Remaining queued messages for that lead on the failed line are marked
-
For leads with only queued (never sent) messages on that line:
- Messages are reassigned to another active line in the campaign, if one exists.
-
If all lines in a campaign fail:
- The campaign is paused until at least one line is healthy again.
Why do I see many 'failed' statuses?
Why do I see many 'failed' statuses?
- Persistent line health issues (device/app offline, misconfigured server URL).
- Provider-level hard errors (invalid numbers/emails, blocked sends).
- Misconfigured workers endpoint for message webhooks or health checks.
- Line health in your Tuco dashboard.
- Worker logs for error messages.
- Underlying iMessage/SMS provider status.
How do per-line limits interact with multiple campaigns?
How do per-line limits interact with multiple campaigns?
- Multiple campaigns can share the same lines.
- Workers compute usage across all messages from a line when deciding if a new message is allowed.
- Older campaigns are prioritized (sorted by
startedAt).
queued until the next day.Webhooks
What webhooks should I implement first?
What webhooks should I implement first?
- Message webhooks (
/api-reference/message-webhooks):message.deliveredmessage.fallback
- Optionally, generic
/webhookevents from/api-reference/endpoint/webhookfor:lead.created,lead.updated,availability.checked, etc.
- Accurate message and campaign stats in your own systems.
- A foundation for CRM sync and analytics.
How should I secure message webhooks from workers?
How should I secure message webhooks from workers?
- Configure a
SERVICE_TOKENenv variable in your app and workers. - Require
Authorization: Bearer <SERVICE_TOKEN>orX-Service-Token: <SERVICE_TOKEN>on/api/webhooks/v1-message. - Reject any requests where the token does not match.
Do I need to support retries or idempotency?
Do I need to support retries or idempotency?
- Webhooks are retried when your endpoint:
- Times out.
- Returns non-2xx responses.
- You should:
- Implement idempotency by
(messageId, event)combination. - Make database updates idempotent (e.g. upserts or
updateOnewith$set).
- Implement idempotency by
API & Integration Questions
Which token should I use for the API: Clerk token or Tuco API key?
Which token should I use for the API: Clerk token or Tuco API key?
- For first-party use (your own backend talking to the Tuco app), Clerk or Tuco auth tokens may be used per the
/api-reference/introduction. - For integrations (e.g. HubSpot backend, third-party services), use a dedicated Tuco API key:
- Easier to rotate.
- Clean workspace scoping.
- Safer to store in environment variables.
How do I handle 402 READ_ONLY errors?
How do I handle 402 READ_ONLY errors?
402 READ_ONLY means the workspace is temporarily in read-only mode, often due to billing.- Do not keep retrying writes; they will continue to fail.
- Surface a clear message in your UI:
- “Tuco workspace is in read-only mode, please update billing in Tuco.”
- Reads may still work; only writes are blocked.
Can I use Tuco from my front-end directly?
Can I use Tuco from my front-end directly?
- You would have to expose API keys or secure tokens in client code (unsafe).
- It is harder to centralize error handling, rate limiting, and idempotency.
- Your front-end calls your backend.
- Your backend calls Tuco APIs with secure credentials.
HubSpot Integration
How does the HubSpot integration talk to Tuco?
How does the HubSpot integration talk to Tuco?
plugins/hubspot-backend) uses:- HubSpot OAuth to get CRM permissions.
- A workspace-specific Tuco API key to:
- List lines (
/api/lines/by-user). - Send messages (
/api/messages). - Record activity back in HubSpot via timeline events.
- List lines (
What if a HubSpot workflow action fails to send?
What if a HubSpot workflow action fails to send?
- Missing/invalid Tuco API key.
- No active lines in the Tuco workspace.
- HubSpot contact missing phone/email.
- Backend logs for
actions.routes.tsandtuco.service.ts. - That you have at least one active line in Tuco.
- That contact data in HubSpot maps correctly to Tuco fields.