Ta strona nie została jeszcze przetłumaczona na Twój język. Wyświetlamy wersję angielski (Wielka Brytania).

Connected inboxes

Connect, reconnect and disconnect your inboxes, choose their calendars, and email or message leads from them.

A connected inbox (in the API, a connected account) is a mailbox, WhatsApp, Instagram, LinkedIn or Telegram account a member connected to Fondaro. Use these endpoints to manage inboxes and to email or message a lead from them; every email and message goes out from the person's own account.

These endpoints take a signed-in member's session token (Authorization: Bearer <session-token>); API keys do not open them. See Authentication.

Base URL: https://api.fondaro.com. Each member connects at most one inbox of each kind. Connecting is a browser round trip: you get a link, the person signs in with the provider, and Fondaro never receives a password.

The connected account object

FieldTypeDescription
iduuid
kindstringmailbox, shared_mailbox, whatsapp, instagram, linkedin or telegram
providerstringgoogle, microsoft, imap (other mailbox), or the chat channel's own name
addressstring or nullThe email address, number or handle, once known
statusstringconnecting, ok, needs_reconnect, error or disconnected
statusReasonstring or nullWhy the status last changed
statusChangedAtstringISO 8601
capabilitiesstring[]What works now: email, calendar, messaging
connectedAtstring or nullISO 8601
disconnectedAtstring or nullAlways null in lists
ownerUserIdstringThe member who connected it
assignedUserIdsstring[]Other people an admin gave this inbox to
calendarsobject[]Only with the calendar capability. See Choose which calendars show

needs_reconnect means the provider stopped accepting the connection (a changed password, or access removed). Reconnecting restores it with the same id.

List your inboxes

GET /connected-accounts

Returns your live inboxes and the colleagues' inboxes an admin gave you. available is false when connecting is not available; the lists are then empty.

bash
curl "https://api.fondaro.com/connected-accounts" \  -H "Authorization: Bearer $SESSION_TOKEN"
json
{  "available": true,  "accounts": [    {      "id": "3c9e2f41-7b1d-4c8a-9e53-0a6d2b7f1e84",      "kind": "mailbox",      "provider": "google",      "address": "agent@example.com",      "status": "ok",      "statusReason": null,      "statusChangedAt": "2026-09-25T09:14:03.000Z",      "capabilities": ["email", "calendar"],      "connectedAt": "2026-09-25T09:14:03.000Z",      "disconnectedAt": null,      "ownerUserId": "user_2a",      "assignedUserIds": [],      "calendars": [        { "id": "agent@example.com", "name": "agent@example.com", "primary": true, "readOnly": false, "selected": true }      ]    }  ],  "assigned": []}

List the organization's inboxes

GET /connected-accounts/organization

Admins only. Returns every member's live inboxes as an array. Each item adds owner (name, email, imageUrl) and included (true when it is one of the plan's included inboxes, the oldest ones; false when it is one of the extra inboxes bought).

bash
curl "https://api.fondaro.com/connected-accounts/organization" \  -H "Authorization: Bearer $SESSION_TOKEN"
json
[  {    "id": "3c9e2f41-7b1d-4c8a-9e53-0a6d2b7f1e84",    "kind": "mailbox",    "provider": "microsoft",    "address": "agent@example.com",    "status": "needs_reconnect",    "ownerUserId": "user_2b",    "assignedUserIds": [],    "owner": { "name": "Agent Name", "email": "agent@example.com", "imageUrl": null },    "included": true  }]

Check the price of the next inbox

GET /connected-accounts/price

Returns whether the next inbox fits in your organization's inboxes, how many are free, the price of one extra inbox, and whether you may add one to the plan yourself.

bash
curl "https://api.fondaro.com/connected-accounts/price" \  -H "Authorization: Bearer $SESSION_TOKEN"
json
{  "included": false,  "room": 0,  "amountCents": 1000,  "currency": "EUR",  "canAddPaid": false,  "requests": [    { "id": "6f0c1d2e-8a3b-4c5d-9e7f-0a1b2c3d4e5f", "kind": "whatsapp", "provider": "whatsapp", "status": "pending", "askedAt": "2026-09-30T09:12:00.000Z", "answeredAt": null }  ]}
FieldDescription
includedtrue while fewer inboxes are connected than your organization has (included plus bought), so anyone on the team can connect the next one
roomHow many inboxes are still free. Absent for an organization with no limit
amountCents, currencyThe monthly price of one extra inbox, in minor units
canAddPaidtrue for an admin, who can add an inbox to the plan (Change your inboxes); false for a member, who asks an admin
requestsYour own open requests (see Ask for an inbox), pending or allowed

GET /billing/plan-usage returns the plan's people and inbox totals:

json
{  "inboxes": {    "included": 5,    "bonus": 0,    "bought": 2,    "capacity": 7,    "inUse": 6,    "room": 1,    "pricePerInbox": 1000,    "monthlyBought": 2000  }}

included is one inbox per member plus any bonus; capacity is included + bought; room is capacity - inUse, never below 0. monthlyBought is null for a member.

Change your inboxes

Admins only. Each extra inbox is a monthly charge on your plan, like a person. inboxes is always the total after the change (included plus bought).

GET /billing/inboxes/preview?inboxes=7 previews the change without making it:

bash
curl "https://api.fondaro.com/billing/inboxes/preview?inboxes=7" \  -H "Authorization: Bearer $SESSION_TOKEN"
json
{  "currency": "EUR",  "dueToday": 640,  "lines": [{ "description": "Remaining time on 1 × Extra inboxes", "amount": 640 }],  "nextAmount": 2000,  "nextDate": "2026-11-01T00:00:00.000Z",  "inboxes": { "from": 6, "to": 7, "included": 5, "bonus": 0, "boughtFrom": 1, "boughtTo": 2, "inUse": 6, "pricePerInbox": 1000 }}

PATCH /billing/inboxes makes it. Send a fresh requestId per change and the same one when you retry it, so a retry never adds twice.

bash
curl -X PATCH "https://api.fondaro.com/billing/inboxes" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"inboxes": 7, "requestId": "3a1f2b4c-5d6e-4f70-8a9b-0c1d2e3f4a5b"}'
json
{ "inboxes": 7, "bought": 2, "inUse": 6 }

Adding inboxes is charged now for the rest of the billing period, and lands only once that payment succeeds (402 PAYMENT_ACTION_REQUIRED otherwise). Removing inboxes credits the unused days on the next invoice. During a trial nothing is charged until it ends.

StatusCodeWhen
400below_includedFewer than the inboxes your plan includes
409inboxes_in_useFewer than the inboxes connected now. The body lists the newest ones in connected (id, ownerName, kind, address): disconnect one first
409BILLING_STATE_CONFLICTNo active plan, or an organization with no limit
402PAYMENT_ACTION_REQUIREDThe card was not charged; nothing changed

Connect an inbox

POST /connected-accounts/connect

Starts a connection and returns a url to open in the person's browser. They return to the matching Integrations page with ?connected=<provider> on success or ?connect_error=<reason> on failure.

ParameterInTypeRequiredDescription
providerBodystringYesgoogle, microsoft, imap, whatsapp, instagram, linkedin or telegram
kindBodystringNoDefaults to mailbox for an email provider, else the provider. shared_mailbox (the agency's shared inbox) is for admins only
bash
curl -X POST "https://api.fondaro.com/connected-accounts/connect" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"provider": "google"}'
json
{ "url": "https://..." }

The inbox appears in GET /connected-accounts once the provider confirms it; poll until status is ok.

When every inbox is in use, connecting is refused with the facts in the body (capacity, inUse, pricePerInbox): an admin gets 409 inboxes_full (add an inbox first with PATCH /billing/inboxes), a member 403 admin_approval_required (ask for one). Connecting itself never charges anything.

Ask for an inbox

POST /connected-accounts/requests

When every inbox is in use, a member asks the admins instead (body as for connect). While one is free, asking returns 409 not_needed: connect instead. Admins see the request in their Inbox and get a notification. Asking again for the same kind returns the open request.

bash
curl -X POST "https://api.fondaro.com/connected-accounts/requests" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"provider": "whatsapp"}'
json
{ "id": "6f0c1d2e-8a3b-4c5d-9e7f-0a1b2c3d4e5f", "kind": "whatsapp", "provider": "whatsapp", "status": "pending", "askedAt": "2026-09-30T09:12:00.000Z", "answeredAt": null }

Admins list open requests with GET /connected-accounts/requests (each adds userId, requester and the monthly amountCents and currency), and answer with POST /connected-accounts/requests/:id/allow or POST /connected-accounts/requests/:id/decline. Allowing tells the member they can connect. They connect while an inbox is free, so when every inbox is in use, add one with PATCH /billing/inboxes before allowing. Answering a request that is no longer open returns 409 request_closed.

Give an inbox to other people

PUT /connected-accounts/:id/assignees

Admins only. Sets everyone besides the owner who uses this inbox (such as the agency's info@). They see its new conversations and can send from it. Replaces the whole list.

ParameterInTypeRequiredDescription
idPathuuidYesThe connected account
userIdsBodystring[]YesUp to 200 member user ids. [] removes everyone
bash
curl -X PUT "https://api.fondaro.com/connected-accounts/8d2a61f0-5c3e-4b7a-a1d9-6e4f0b2c7a15/assignees" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"userIds": ["user_2b", "user_2c"]}'
json
{ "id": "8d2a61f0-5c3e-4b7a-a1d9-6e4f0b2c7a15", "kind": "shared_mailbox", "address": "info@example.com", "assignedUserIds": ["user_2b", "user_2c"] }

Reconnect an inbox

POST /connected-accounts/:id/reconnect

Returns a url, as for connect. Only the member who connected the inbox can reconnect it. It keeps its id and uses no extra inbox.

bash
curl -X POST "https://api.fondaro.com/connected-accounts/3c9e2f41-7b1d-4c8a-9e53-0a6d2b7f1e84/reconnect" \  -H "Authorization: Bearer $SESSION_TOKEN"
json
{ "url": "https://..." }

Disconnect an inbox

DELETE /connected-accounts/:id

Disconnects at once and answers 204 with no body. The owner or any admin can disconnect. Conversations already on leads stay. There is no refund for the current month.

bash
curl -X DELETE "https://api.fondaro.com/connected-accounts/3c9e2f41-7b1d-4c8a-9e53-0a6d2b7f1e84" \  -H "Authorization: Bearer $SESSION_TOKEN"

Choose which calendars show

A Google or Microsoft inbox with the calendar capability lists its calendars in calendars. A calendar someone else owns and shared into the inbox is listed only when the inbox's owner is an organization admin; for a member it is left out and its events leave their calendar.

FieldTypeDescription
idstringThe provider's calendar id. URL-encode it in a path
namestring or nullAs named in Google or Outlook
primarybooleanThe main calendar. It always shows
readOnlybooleanShared for reading only. New events never go to it
selectedbooleanIts events show on the person's calendar. A new calendar starts hidden, except the primary

PUT /connected-accounts/:id/calendars/:calendarId with { "selected": true | false } shows or hides one calendar. POST /connected-accounts/:id/calendars/refresh (no body) lists the calendars again, for one made after connecting. Both act on your own inbox only and answer { "calendars": [...] }.

bash
curl -X PUT "https://api.fondaro.com/connected-accounts/3c9e2f41-7b1d-4c8a-9e53-0a6d2b7f1e84/calendars/viewings%40group.calendar.google.com" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"selected": false}'
json
{  "calendars": [    { "id": "agent@example.com", "name": "agent@example.com", "primary": true, "readOnly": false, "selected": true },    { "id": "viewings@group.calendar.google.com", "name": "Viewings", "primary": false, "readOnly": false, "selected": false }  ]}

Email a lead

See which address you send from

GET /crm/email-sender

Returns how an email you send now would leave, so a composer can show the From address or a Connect step.

bash
curl "https://api.fondaro.com/crm/email-sender" \  -H "Authorization: Bearer $SESSION_TOKEN"
json
{  "via": "mailbox",  "address": "sofia@example.com",  "status": "ok",  "accountId": "3c9e2f41-7b1d-4c8a-9e53-0a6d2b7f1e84",  "options": [    { "accountId": "3c9e2f41-7b1d-4c8a-9e53-0a6d2b7f1e84", "address": "sofia@example.com", "via": "mailbox" },    { "accountId": "8d2a61f0-5c3e-4b7a-a1d9-6e4f0b2c7a15", "address": "info@example.com", "via": "shared_mailbox" }  ]}

via is mailbox or none (nothing to send from). An inbox that needs reconnecting still answers mailbox with its status. options lists every inbox you may pick as From whose status is ok: your own, then those an admin gave you.

Send an email

POST /crm/leads/:id/emails

Sends from your connected mailbox. It lands in your Sent folder, and the lead's reply comes back to your inbox and onto the lead.

ParameterInTypeRequiredDescription
idPathintegerYesThe lead
subjectBodystringYesUp to 500 characters
bodyTextBodystringYesThe plain version, always stored
bodyHtmlBodystringNoFormatted body, up to 100,000 characters, cleaned to basic text tags and http, https or mailto links
fromAccountIdBodyuuidNoOne of your options. Default: your own mailbox
cc, bccBodystring[]NoUp to 10 addresses each
signatureHtmlBodystringNoYour signature, cleaned before sending
replyToEmailIdBodyuuidNoAn email on the lead's timeline to reply to, so it threads
documentIdsBodyuuid[]NoUp to 10 uploaded Documents to attach, 20 MB together
bash
curl -X POST "https://api.fondaro.com/crm/leads/4821/emails" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"subject": "Re: The villa in Nueva Andalucía", "bodyText": "Saturday at 11 works for me.", "replyToEmailId": "b7e1c5d2-4a3f-4e8b-9c61-2d0f7a9e5b13"}'

The response is the email as it now sits on the lead's timeline, with toAddresses, ccAddresses and bccAddresses.

Find past emails

POST /crm/leads/:id/find-past-emails

Searches your connected inboxes for the lead's email address over the last 12 months and adds what it finds to the lead within a minute or two. Use it for a lead created after you connected (connecting brings in the last 90 days once). Safe to repeat. Answers 202.

bash
curl -X POST "https://api.fondaro.com/crm/leads/4821/find-past-emails" \  -H "Authorization: Bearer $SESSION_TOKEN"
json
{ "mailboxes": 1, "found": 6, "enqueued": 4 }

Message a lead

List the lead's channels

GET /crm/leads/:id/channels

Lists the channels you can message this lead on: you have a live WhatsApp, Instagram, LinkedIn or Telegram connection and the lead is reachable there (on WhatsApp by their number, elsewhere because they wrote to you or a member linked their profile). An empty list means no message channel.

bash
curl "https://api.fondaro.com/crm/leads/4821/channels" \  -H "Authorization: Bearer $SESSION_TOKEN"
json
{  "channels": [    {      "channel": "whatsapp",      "canSend": true,      "block": null,      "integration": "whatsapp",      "accountAddress": "+34600000001",      "counterpart": "+34600000002",      "newChat": true,      "manyNewChats": false    }  ]}

block says why canSend is false: needs_reconnect or restricted (the provider restricted the account). newChat is true when the next message opens a chat with someone new. manyNewChats is true when it does and the account has already started many new chats in the last 24 hours: advice to spread them out, never a block.

Send a message

POST /crm/leads/:id/messages

Sends from your own connection of that channel. A person sends every message: there is no scheduled, bulk or automated sending.

ParameterInTypeRequiredDescription
idPathintegerYesThe lead
channelBodystringYeswhatsapp, instagram, linkedin or telegram
bodyBodystringYesUp to 4,000 characters. May be empty when a file goes alone
attachmentsBodyuuid[]NoUp to 3 uploaded Documents ids, 10 MB together
bash
curl -X POST "https://api.fondaro.com/crm/leads/4821/messages" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"channel": "whatsapp", "body": "Saturday at 11 works for me."}'
json
{  "id": "6a1f0c3e-2b7d-4e59-8c14-9d3a5e7b2f60",  "leadId": 4821,  "channel": "whatsapp",  "kind": "text",  "direction": "outbound",  "status": "sent",  "body": "Saturday at 11 works for me.",  "attachments": [],  "messageAt": "2026-09-25T10:04:00.000Z"}

To protect your account, messages from one account go at least 15 seconds apart (Instagram 10 seconds, and at most 10 an hour); a send inside that gap waits up to 30 seconds. A first message to someone new is never held back.

GET /crm/leads/:id/messages/:messageId/attachments/:index returns a short-lived download link (url, filename, contentType) for a stored file on a message.

Link a WhatsApp number, Instagram, LinkedIn or Telegram identity, or an extra email address, to a lead so messages there land on it.

Method and pathPurpose
GET /crm/leads/:id/channel-identitiesThe identities linked to the lead
POST /crm/leads/:id/channel-identities/lookupWho that is on the channel, before linking. Writes nothing
POST /crm/leads/:id/channel-identitiesLink it, and attach what they already wrote
DELETE /crm/leads/:id/channel-identities/:identityIdUnlink it (204)
POST /crm/leads/:id/find-past-messagesRead the last year of the lead's chats on your own accounts
bash
curl -X POST "https://api.fondaro.com/crm/leads/4821/channel-identities" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"channel": "whatsapp", "value": "+34600000002"}'
json
{  "identity": { "id": "1d2e3f40-5a6b-4c7d-8e9f-0a1b2c3d4e5f", "channel": "whatsapp", "display": "+34600000002", "linkedBy": "user_2a", "createdAt": "2026-09-25T10:00:00.000Z" },  "attachedMessages": 3,  "attachedEmails": 0}

Look up a lead's profile

POST /crm/leads/:id/lookup-profile

Reads the lead's linked LinkedIn or Instagram profile once, through your own connection. It changes nothing on the lead. LinkedIn allows about 80 look ups a day per account.

bash
curl -X POST "https://api.fondaro.com/crm/leads/4821/lookup-profile" \  -H "Authorization: Bearer $SESSION_TOKEN" \  -H "Content-Type: application/json" \  -d '{"channel": "linkedin"}'
json
{  "channel": "linkedin",  "identity": "sample-buyer",  "name": "Sample Buyer",  "headline": "Relocating to Marbella",  "company": "Example Ltd",  "location": "London",  "category": null,  "emails": [],  "phones": [],  "profileUrl": "https://www.linkedin.com/in/sample-buyer"}

Errors

StatusCodeWhen
400invalid_kindThe kind cannot use that provider
400not_a_memberAn assignee is not in your organization
400sender_not_allowedfromAccountId is not one of your options
400lead_has_no_emailFind past emails on a lead with no email address
402not_entitledConnecting needs an active plan or trial
403ORG_ADMIN_REQUIREDAn admin-only action, or the shared mailbox
403admin_approval_requiredA member connecting when every inbox is in use. Ask for one
403not_ownerReconnecting or disconnecting someone else's inbox
403sandbox, SANDBOX_OUTBOUND_DISABLEDSandbox organizations cannot connect inboxes or send
403mailbox_not_connected, mailbox_needs_reconnectSending an email without a working mailbox
403message_not_connected, message_needs_reconnect, message_account_restrictedSending a message without a working connection
403SUBSCRIPTION_REQUIREDA lead write without an active plan
404CONNECTED_ACCOUNT_NOT_FOUND, CALENDAR_NOT_FOUND, lookup_not_foundNot found, or not yours
409already_connectedYou already have a live inbox of this kind
409inboxes_fullAn admin connecting when every inbox is in use. Add one first
409not_needed, request_closedNo request is needed, or it is no longer open
409CALENDAR_PRIMARY_LOCKED, CONNECTED_ACCOUNT_NEEDS_RECONNECTHiding the primary calendar, or refreshing an inbox that needs reconnecting
409mailbox_not_connected, mailbox_needs_reconnectFind past emails without a working mailbox
409channel_linked_elsewhereThe identity is linked to another lead
422message_not_on_channel, channel_invalid, lookup_not_linkedThe lead is not reachable there, the value is not valid, or no profile is linked
429message_paced, message_rate_limited, mailbox_rate_limited, lookup_limitedTry again after retryAfterSeconds
502message_send_failed, mailbox_send_failed, provider_errorThe provider did not take it; try again
503not_availableConnecting is not available

Errors use the standard body { "statusCode", "message", "error" }, plus code and any fields listed above.