Skip to navigation

Robot settings

A robot carries the same settings your customer sees in the ParsChat panel: when an idle conversation closes, what a customer is told when a person takes over, the team’s working hours, and how the AI answers. Read them on every robot response, and change any of them with one call:

curl -X PATCH "https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ" \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"settings": {"conversations": {"auto_close": {"idle_minutes": 720}}}}'

The answer is the whole robot, with every setting as it now stands.

Reading the settings

settings is on every robot you receive: GET /robots/{robot_id}, every item of GET /robots, and the answers to POST /robots and PATCH /robots/{robot_id}.

Response
{
"id": "rbt_8fK2mQ",
"name": "Rose Flower Shop",
"external_id": "shop_10422",
"description": "Flower shop on Instagram",
"is_active": true,
"channels": [{ "id": "chn_3pQ7xL", "type": "instagram", "is_active": true }],
"created_at": "2026-09-20T11:04:33Z",
"settings": {
"conversations": {
"auto_close": { "enabled": true, "idle_minutes": 360, "max_idle_minutes": 21600 },
"operator_handover": { "message": "An operator will join you shortly.", "send_message": true },
"offline": { "message": "Our team is offline right now; we will reply when we are back.", "send_message": true },
"busy": { "message": "Our operators are busy; we will reply as soon as we can.", "send_message": false, "after_seconds": 300 },
"offline_message": "Our team is offline right now; we will reply when we are back.",
"ai_failure_message": null,
"working_hours": {
"enabled": true,
"time_zone": "Asia/Tehran",
"days": {
"SAT": [{ "start": "09:00", "end": "18:00" }],
"SUN": [{ "start": "09:00", "end": "13:00" }, { "start": "16:00", "end": "20:00" }],
"MON": [{ "start": "09:00", "end": "18:00" }],
"TUE": [{ "start": "09:00", "end": "18:00" }],
"WED": [{ "start": "09:00", "end": "18:00" }],
"THU": [{ "start": "09:00", "end": "13:00" }],
"FRI": []
}
}
},
"ai": {
"enhanced_accuracy": false,
"creativity": 50,
"language": "auto",
"topic": "Flower shop: roses and tulips, delivery inside Tehran only"
},
"ai_operator": {
"enabled": true,
"display_name": "Rose assistant",
"start_mode": "on_first_message",
"availability": "always",
"wait_minutes": 3
}
}
}

A robot that never changed a setting shows the value actually in force, not a placeholder. For auto-close that is today’s rule: {"enabled": true, "idle_minutes": 10080}, a week.

settings.ai and settings.ai_operator are null for an account without an AI messages package. They need a plan that includes AI messages. A package whose messages are used up for this period still counts: the settings do not lock and unlock as the balance runs down.

Changing them

PATCH /robots/{robot_id} takes any subset of these fields:

  • name, external_id, description, is_active
  • settings.conversations, settings.ai, settings.ai_operator

The same settings object is accepted when you create a robot with POST /robots; anything you leave out takes its default.

Only what you send changes, and nested objects merge. Sending {"settings": {"conversations": {"auto_close": {"idle_minutes": 720}}}} keeps enabled as it was. A working-hours days object changes only the days it names.

Four rules hold for every request:

  1. All or nothing. If any part of a request is refused, nothing in it is saved, not even the parts that were valid.
  2. An unknown field is refused with 422, never ignored, so a misspelt field cannot pass as saved.
  3. null is accepted only for external_id and description, and clears them. Anywhere else it is 422: leave a field out to keep it.
  4. An empty body {} changes nothing and returns the robot.

The call needs the robot:create permission on your key, the same one that creates and deletes robots.

Conversations

FieldTypeAllowedDefault
auto_close.enabledbooleantrue
auto_close.idle_minutesinteger15 to 21600 (15 days)10080 (7 days)
auto_close.max_idle_minutesintegerread-only, always 2160021600
operator_handover.messagestringup to 500 characters; required while send_message is onParsChat’s default Persian message
operator_handover.send_messagebooleantrue
offline.messagestringup to 500 characters; required while send_message is onParsChat’s default Persian message
offline.send_messagebooleanfalse
busy.messagestringup to 500 characters; required while send_message is onParsChat’s default Persian message
busy.send_messagebooleanfalse
busy.after_secondsinteger30 to 3600300
offline_messagestringdeprecated: the same text as offline.message; 1 to 500 characters, whitespace only restores the default
ai_failure_messagestringdeprecated and ignored; always null in a responsenull
working_hours.enabledbooleanfalse means every hour is a working hourfalse
working_hours.time_zonestringan IANA time zone, such as Asia/TehranUTC
working_hours.daysobjectkeys SAT SUN MON TUE WED THU FRI; each a list of {"start", "end"} in HH:MM, start before end; [] closes that dayevery day []

When a conversation closes

A conversation with no message for its robot’s idle_minutes is closed, and you receive a chat event with status: "closed". Closing runs hourly, so a conversation closes up to about an hour after its limit.

  • enabled: false does not mean “never”. The conversation still closes after 15 days (21600 minutes) without a message. idle_minutes is kept, so turning auto-close back on restores it.
  • A customer who writes again reopens the same conversation: the same conversation_id, status not_answered, another chat event, and the AI starts from a fresh context.
  • The setting covers every channel ParsChat runs for the robot: Instagram, Telegram, WhatsApp, GAP, the website widget and Direct API. Goftino and Crisp conversations follow those platforms’ own lifecycle.

What the customer is told while waiting for a person

A robot has three messages. Each is sent at most once per conversation.

MessageSent when
operator_handoverThe AI hands the conversation to a person: it asks for one, the customer dislikes an answer, the customer sends a voice message, or the AI cannot answer.
offlineThe customer is waiting for a person while the robot is offline: outside its working_hours.
busyThe customer is waiting for a person while the robot is online, and nobody has replied within after_seconds.
  • operator_handover is sent on every channel, including Goftino and Crisp. It is sent only when the AI was answering: a conversation the AI did not answer (for example, when your AI messages are used up) is not “handed over”, so it gets no operator_handover message.
  • offline and busy are sent on Instagram, Telegram, WhatsApp, GAP and the website widget. Goftino and Crisp have their own settings for these, so they are not sent there.
  • A customer who is waiting is one whose message the AI will not answer: the conversation is with your team, the AI is off, or it does not answer at this time (ai_operator.availability).
  • When the AI is set to answer after wait_minutes (start_mode: "if_operator_not_respond"), the AI’s answer replaces busy.
  • A message switched on needs a text: send_message: true with an empty message is refused with 422.

AI

Needs an AI messages package.

FieldTypeAllowedDefault
enhanced_accuracybooleanchecks every answer before sending it; uses two AI units per messagefalse
creativityinteger0 sticks to your customer’s content, 100 is freest50
languagestringauto (the customer’s own language), persian, english, dutchauto
topicstringwhat the robot answers about, given to the AI with every question""

topic is the panel’s Robot introduction. It takes effect on the next customer message: nothing is retrained and no characters are used. 5 characters or fewer counts as none.

AI operator

Needs an AI messages package.

FieldTypeAllowedDefault
enabledbooleanfalse: the AI never answerstrue
display_namestring1 to 50 characters; the AI’s name in the operator listParsChat’s default Persian name
start_modestringon_first_message, or if_operator_not_respond to wait wait_minutes for a person firston_first_message
availabilitystringonline, offline or always: when, relative to the team being online, the AI answersalways
wait_minutesinteger1 to 10080 (a week); used only by if_operator_not_respond3

Deactivating a robot

{"is_active": false} is the panel’s activation switch, and it is not a pause:

  • Every channel of the robot is switched off (is_active: false on each channel), which frees their channel capacity. Only enabled channels count against your plan.
  • The robot keeps its robot slot: robot capacity counts every robot that exists. Delete the robot to free its slot.
  • {"is_active": true} reactivates the robot but leaves its channels off. Switch each back on with PATCH /robots/{robot_id}/channels/{channel_id}, which checks channel capacity as usual.

To stop only the AI answering while the channels stay live, set settings.ai_operator.enabled to false.

Not in this API

  • The custom prompt. A robot’s prompt changes only through the panel’s prompt assistant, where the AI rewrites the request, reports the parts it refused, and your customer accepts the result. It is not a field you can set here: settings.ai.instructions is refused as an unknown field.
  • The AI operator’s avatar, which is a file upload.
  • Plan controls, such as message limits. They are set by ParsChat.

Examples

Change only the auto-close period

Request
{ "settings": { "conversations": { "auto_close": { "idle_minutes": 720 } } } }

200, the full robot, with "auto_close": {"enabled": true, "idle_minutes": 720, "max_idle_minutes": 21600}.

Turn auto-close off

Request
{ "settings": { "conversations": { "auto_close": { "enabled": false } } } }

200, with "auto_close": {"enabled": false, "idle_minutes": 720, "max_idle_minutes": 21600}. Conversations now close after 15 days without a message.

Several settings at once

Request
{
"name": "Rose Flower Shop (Tehran)",
"settings": {
"conversations": {
"operator_handover": { "send_message": true, "message": "Connecting you to a person." },
"working_hours": {
"enabled": true,
"time_zone": "Asia/Tehran",
"days": { "FRI": [{ "start": "10:00", "end": "14:00" }] }
}
},
"ai_operator": { "start_mode": "if_operator_not_respond", "wait_minutes": 5, "availability": "offline" }
}
}

200. Friday now opens 10:00 to 14:00 and the other six days are unchanged. The AI answers only outside working hours, after 5 minutes without an operator reply, and a customer handed to a person is told “Connecting you to a person.”

Tell waiting customers when the team is offline or busy

Request
{
"settings": {
"conversations": {
"offline": { "send_message": true, "message": "Our team is offline right now; we will reply when we are back." },
"busy": { "send_message": true, "after_seconds": 120 }
}
}
}

200. A customer waiting outside working hours gets the offline message; one waiting for two minutes without a reply during working hours gets the busy message, in ParsChat’s default text.

Change the topic

Request
{ "settings": { "ai": { "topic": "Flower shop: roses, tulips and orchids, delivery across Iran" } } }

200, with the new topic, in effect from the next customer message. "topic": "" removes it.

Clear your own id and description

Request
{ "external_id": null, "description": null }

200, with "external_id": null and "description": null.

Create a robot with settings

curl -X POST "https://api-chat.parstechai.com/v1/robots" \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name": "Orchid Lab", "external_id": "shop_20077",
"settings": {"conversations": {"auto_close": {"enabled": true, "idle_minutes": 1440}}}}'

201, the full robot, with every setting you left out at its default.

When a change is refused

Nothing in a refused request is saved.

RequestAnswer
{"settings": {"ai": {"creativity": 70}}} on an account without an AI package403 ai_not_in_plan: “Your plan does not include AI messages, so AI settings cannot be changed.”
{"settings": {"conversations": {"auto_close": {"idle_minutes": 30000}}}}422 validation_failed: "`settings.conversations.auto_close.idle_minutes`: Input should be less than or equal to 21600"
{"settings": {"conversations": {"auto_close": {"idle_minute": 720}}}} (typo)422 validation_failed: "`settings.conversations.auto_close.idle_minute`: Extra inputs are not permitted"
{"settings": {"conversations": {"offline": {"send_message": true, "message": " "}}}}422 validation_failed: “A message that is switched on needs a text.”, with details.field = settings.conversations.offline.message
{"settings": {"conversations": {"ai_failure_message": "shout"}}}422 validation_failed: "`settings.conversations.ai_failure_message`: Input should be 'offline_message', 'handover_message' or 'none'"
{"settings": {"ai": {"creativity": null}}}422 validation_failed: "`settings.ai.creativity`: Input should be a valid integer"
{"settings": {"ai": {"instructions": "…"}}}422 validation_failed: the custom prompt is not part of this API
{"external_id": "shop_20077"} when another of your robots uses it409 conflict
A robot id that is not yours, or does not exist404 not_found, the same answer for both

The same 422 covers creativity: 150, wait_minutes: 0, "start": "25:00", a window whose start is not before its end, an unknown time_zone, language: "french" and display_name: "". The message names the field by its path; branch on error.code, not on the wording, which may change.