@taskmagic/apps-chatwith
v0.0.3
Published
AI chatbots trained on your own content with [Chatwith](https://chatwith.tools) — API docs: https://api-docs.chatwith.tools/
Downloads
434
Readme
Chatwith
AI chatbots trained on your own content with Chatwith — API docs: https://api-docs.chatwith.tools/
The API is REST under https://api.chatwith.tools/v1 and authenticated with an HTTP Bearer
token: Authorization: Bearer <API key>, with Content-Type: application/json.
- Actions: Send Chat Message, List Chatbots, Get Chatbot, Update Chatbot, List Conversations, Get Conversation, List Knowledge Sources, Add Knowledge Source, Delete Knowledge Source, Resync Knowledge Source.
- Triggers: New Lead (webhook), Conversation Report (webhook), New Or Updated Conversation (polling).
Connection: sign in at chatwith.tools, open the Account page
(chatwith.tools/app/account) and copy the API key shown
there. Chatwith's docs state plainly that "API access is available on paid plans only." Your
Chatbot ID lives on the dashboard Settings page
(chatwith.tools/app/settings), but you rarely need it —
every action that takes one offers a live dropdown of the chatbots on the connected account,
backed by GET /chatbot. The connection is validated with a single GET /me call.
Notes
- Paid plans, and two separate API entitlements. Beyond needing a paid plan at all, Chatwith
prices the Chatbot API and the Management API as separate plan features, and
GET /conversationsdocuments a403 Forbiddenwith "Your plan does not include advanced API access". So a key that happily sends chat messages can still be refused on List Conversations, Get Conversation and the New Or Updated Conversation trigger. Any 403 from this piece names that as the likely cause alongside "this key has no access to that chatbot". - Send Chat Message always runs in non-streaming JSON mode.
streamis hardcoded tofalseandAccept: application/jsonis always sent, because Chatwith's docs say "Using the non-streaming mode in JSON mode is currently the only way to receive the conversation ID." A streamed reply would leave a flow with no way to continue the thread, so streaming is not exposed as an option. Pass the returnedconversationIdback into the action's Conversation ID field to keep the same conversation going; leave it blank to start a new one. - Send Chat Message has a 60 second budget, not 30. Chatwith documents a 60 second maximum
execution time on
POST /chatbot/{id}/chat— it covers the bot running its own Actions and skills plus generation. That one action is therefore given a 60 000 ms timeout; every other call in this piece is bounded at 30 000 ms. - The reply field is read defensively. The prose docs return
{ text, conversationId }; an older embeddedopenapi.ymlsketched the 200 as{ messages: [...] }. The action preferstext, falls back to joiningmessages, and always returns the untouched response underraw. - Rate limits on the chat endpoint: 100 requests per minute per chatbot ID, and 10 requests per minute per unique IP address.
- Credits are per message and depend on the model. GPT-5.2 = 10, Claude Sonnet 4.5 = 10, Claude Opus 4.6 = 15, GPT-5.2-mini = 2, Gemini Flash 2.5 = 3. Switching a chatbot's model with Update Chatbot changes what every subsequent message costs.
- Update Chatbot always resends the name.
PUT /chatbot/{id}takes a wholeChatbotBase, andchatbotNameis its only required field — a partial update that omitted it would fail or blank the name. Leave the Name field empty and the action fetches the chatbot's current name first and sends that back unchanged. Every other field you leave empty is omitted from the request body entirely, so an update never overwrites a setting the flow did not touch. - The optional booleans are dropdowns, not checkboxes.
showBrandedFooterandshowActionIndicatorsare nullable booleans. An untouched optional checkbox persists asfalserather thanundefined, which would silently switch both off on every update, so they are three-state dropdowns (Leave unchanged / Yes / No) instead. - Two Update Chatbot fields cannot be cleared.
maxMessagesLimitHardandallowedDomainsare only ever set — leaving them empty means "leave unchanged", so there is no way from here to sendmaxMessagesLimitHard: null(no limit) or an empty domain allow-list. Clear those in the dashboard. Supplying any Allowed Domains value replaces the whole list. - Activation is a timestamp, not a flag. Chatwith models deactivation as a nullable
deactivatedAtdate, and setting it tonullreactivates a chatbot. The Activation dropdown maps Active todeactivatedAt: nulland Deactivated to the current time; the docs only spell out the reactivate direction, so the deactivate direction is our reading of the schema. - Knowledge sources can only be added as URLs. Chatwith's own wording: "the API only allows
adding knowledge sources of type URL. Only websites and links to PDF files are supported."
Text, file and YouTube sources have to be added in the dashboard, even though the API returns
all four types.
POST /chatbot/{id}/sourcesanswers with an array, because one URL can expand into several sources. The optional Content field seeds the source with your own text instead of fetching the URL — but if Auto Train is enabled, that content will eventually be replaced by the content from the URL. - Resync Knowledge Source is lightly documented.
POST /sources/{id}/syncexists in Chatwith's OpenAPI YAML but is not rendered on the knowledge sources documentation page. It also does not answer with JSON: success is the literal string"OK"and the documented 500 is the literal string"Error", so the action handles a non-JSON body and fails the step on anything that is notOK. - Webhook triggers must be registered by hand — there is no webhook API. Chatwith has no endpoint that creates, lists or deletes a webhook; notification destinations exist only in the dashboard under Settings → Notifications (up to 5 email and/or webhook destinations, with webhook destinations gated to higher plans). New Lead and Conversation Report therefore cannot self-register: copy the webhook URL the trigger shows you and paste it into that Notifications tab. For the same reason they have nothing to tear down on disable — remove the destination in Chatwith yourself when you are done, or it will keep posting.
- Conversation Report is periodic, not per-event. It arrives on the daily or weekly schedule
set in the dashboard, and its payload is an array of conversations. The trigger starts one
flow run per conversation in the report. Each conversation carries its messages and, when the
lead form was filled in, a
leadobject. - New Or Updated Conversation dedupes on
updatedAt, deliberately.GET /conversationsis already ordered by last update date, most recent first, so the trigger keeps a watermark on each conversation'supdatedAtand fires again only when it advances. Keying on the conversationidalone would never fire for new messages on an existing conversation; keying a last-item cursor onid + updatedAtwould replay the whole 50-row page every time the top-of-list conversation received another message. Only page 1 is polled. - Message-level dedupe is impossible over REST. The REST
Messageschema has no messageidat all — only the webhook payload carries one — so nothing here keys off a per-message identifier. - No "list leads" action. Chatwith has no leads endpoint. Leads are available only in the
dashboard, through the New Lead webhook, and as the
leadfield on the conversation report webhook payload — they are not on the RESTConversationschema. - Error bodies are not documented. Chatwith only says it returns appropriate status codes
"along with error messages in the response body"; no
errorormessagefield name is published anywhere. So this piece parses nothing out of an error body — it reports the status code with actionable wording (400, 401, 403, 404, 429, 5xx) and appends a truncated copy of the raw body as a hint. The API key never appears in an error message. - No custom API call action. A passthrough would hand this connection's API key to any URL a flow supplies, and every documented endpoint is already covered above.
