Menu

Reference

AI Setter

AI Setter: 9 operations (setter.knowledge.list, setter.knowledge.create, setter.booking.preview, setter.connections.get, setter.knowledge.update, setter.knowledge.delete, setter.persona.get, setter.persona.set, setter.test).

MethodPathOperation
GET/v1/reps/{rep_id}/setter/knowledgesetter.knowledge.list
POST/v1/reps/{rep_id}/setter/knowledgesetter.knowledge.create
GET/v1/setter/booking-previewsetter.booking.preview
GET/v1/setter/connectionssetter.connections.get
PATCH/v1/setter/knowledge/{knowledge_id}setter.knowledge.update
DELETE/v1/setter/knowledge/{knowledge_id}setter.knowledge.delete
GET/v1/setter/personasetter.persona.get
PUT/v1/setter/personasetter.persona.set
POST/v1/setter/testsetter.test

setter.knowledge.list

GET/v1/reps/{rep_id}/setter/knowledge

List a rep's AI Setter knowledge entries, oldest first.

Operation idsetter.knowledge.list
Scopessetter:read
Rate class`read`
IdempotencyNot applicable
KeysDeveloper keys
RepsA key restricted to reps sees only data of its own reps

Path parameters

NameTypeRequiredDescription
rep_idstringyes

Response 200

FieldTypeRequiredDescription
dataobject[]yes

Errors

StatusCodeWhen
404`REP_NOT_FOUND_404`A rep does not exist in this workspace, is archived, or is outside the key's rep restriction.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl "https://api.dmhero.ai/v1/reps/string/setter/knowledge" \
  -H "Authorization: Bearer $DMHERO_API_KEY"
JSON Schema
Response 200
{
  "type": "object",
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "rep_id": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "title": {
            "type": "string"
          },
          "content": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          }
        },
        "required": [
          "id",
          "rep_id",
          "title",
          "content",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "data"
  ],
  "additionalProperties": false
}

setter.knowledge.create

POST/v1/reps/{rep_id}/setter/knowledge

Add a knowledge entry the rep's AI Setter may answer from.

The setter reads every entry of the rep on every reply. The same limits as the app's editor: a title of 1 to 120 characters after trimming, content up to 8000 characters.

Operation idsetter.knowledge.create
Scopessetter:write
Rate class`write`
Idempotency`Idempotency-Key` accepted
KeysDeveloper keys
RepsA key restricted to reps sees only data of its own reps

Path parameters

NameTypeRequiredDescription
rep_idstringyes

Request body

FieldTypeRequiredDescription
contentstringyesUp to 8000 characters.. at most 8000 characters
titlestringyes1 to 120 characters after trimming.

Response 201

FieldTypeRequiredDescription
contentstringyes
created_atdate-timeyes
iduuidyes
rep_iduuidyes
titlestringyes
updated_atdate-timeyes

Errors

StatusCodeWhen
400`VALIDATION_FAILED_400`A field is missing or malformed; fields names each one.
404`REP_NOT_FOUND_404`A rep does not exist in this workspace, is archived, or is outside the key's rep restriction.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X POST "https://api.dmhero.ai/v1/reps/string/setter/knowledge" \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "string",
  "content": "string"
}'
JSON Schema
Request body
{
  "type": "object",
  "properties": {
    "title": {
      "type": "string",
      "description": "1 to 120 characters after trimming."
    },
    "content": {
      "type": "string",
      "maxLength": 8000,
      "description": "Up to 8000 characters."
    }
  },
  "required": [
    "title",
    "content"
  ]
}
Response 201
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "rep_id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "title": {
      "type": "string"
    },
    "content": {
      "type": "string"
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
    }
  },
  "required": [
    "id",
    "rep_id",
    "title",
    "content",
    "created_at",
    "updated_at"
  ],
  "additionalProperties": false
}

setter.booking.preview

GET/v1/setter/booking-preview

The free meeting times a variant's saved booking rules would offer a new prospect right now.

Reads the workspace's Google Calendar free/busy under the variant's SAVED booking rules and writes nothing. block is the text the setter's model reads. A calendar that is not connected, revoked, or refused by Google is not an error: available is false and reason says why.

Operation idsetter.booking.preview
Scopessetter:read
Rate class`heavy`
IdempotencyNot applicable
KeysDeveloper keys
RepsA key restricted to reps sees only data of its own reps

Query parameters

NameTypeRequiredDescription
variant_idstringyes
lang"pl" | "en"noLanguage of block. Default pl.

Response 200

FieldTypeRequiredDescription
availablebooleanyes
beyond_horizonboolean | nullyes
blockstring | nullyes
emptyboolean | nullyes
first_available_datestring | nullyes
owner_tzstring | nullyes
prospect_tzstring | nullyes
reasonstring | nullyesWhy no times could be read, when available is false.

Errors

StatusCodeWhen
403`GOOGLE_CALENDAR_NOT_ENABLED_403`Google Calendar booking is not enabled for this organization yet.
404`SETTER_VARIANT_NOT_FOUND_404`The setter variant does not exist, or belongs to a rep outside the key's reps.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl "https://api.dmhero.ai/v1/setter/booking-preview?variant_id=string" \
  -H "Authorization: Bearer $DMHERO_API_KEY"
JSON Schema
Response 200
{
  "type": "object",
  "properties": {
    "available": {
      "type": "boolean"
    },
    "reason": {
      "description": "Why no times could be read, when `available` is false.",
      "type": [
        "string",
        "null"
      ]
    },
    "block": {
      "type": [
        "string",
        "null"
      ]
    },
    "empty": {
      "type": [
        "boolean",
        "null"
      ]
    },
    "beyond_horizon": {
      "type": [
        "boolean",
        "null"
      ]
    },
    "first_available_date": {
      "type": [
        "string",
        "null"
      ]
    },
    "owner_tz": {
      "type": [
        "string",
        "null"
      ]
    },
    "prospect_tz": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "required": [
    "available",
    "reason",
    "block",
    "empty",
    "beyond_horizon",
    "first_available_date",
    "owner_tz",
    "prospect_tz"
  ],
  "additionalProperties": false
}

setter.connections.get

GET/v1/setter/connections

Whether the workspace's Google Calendar and Calendly are connected, for the setter's booking goal.

Status only: the state of each connection, the Google account and its calendars (to pick a target calendar for a variant's booking rules), the Calendly scheduling link. Never a token.

Operation idsetter.connections.get
Scopessetter:read
Rate class`read`
IdempotencyNot applicable
KeysDeveloper keys

Response 200

FieldTypeRequiredDescription
calendlyobjectyes
google_calendarobjectyes

Errors

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl "https://api.dmhero.ai/v1/setter/connections" \
  -H "Authorization: Bearer $DMHERO_API_KEY"
JSON Schema
Response 200
{
  "type": "object",
  "properties": {
    "google_calendar": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean",
          "description": "Google Calendar booking is available to this organization."
        },
        "connected": {
          "type": "boolean"
        },
        "status": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "active",
                "incomplete",
                "revoked"
              ]
            },
            {
              "type": "null"
            }
          ]
        },
        "email": {
          "type": [
            "string",
            "null"
          ]
        },
        "owner_timezone": {
          "type": [
            "string",
            "null"
          ]
        },
        "missing_scopes": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "calendars": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "summary": {
                "type": "string"
              },
              "primary": {
                "type": "boolean"
              },
              "time_zone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "access_role": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "summary",
              "primary",
              "time_zone",
              "access_role"
            ],
            "additionalProperties": false
          }
        },
        "calendars_fetched_at": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
            },
            {
              "type": "null"
            }
          ]
        },
        "connected_at": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "required": [
        "enabled",
        "connected",
        "status",
        "email",
        "owner_timezone",
        "missing_scopes",
        "calendars",
        "calendars_fetched_at",
        "connected_at"
      ],
      "additionalProperties": false
    },
    "calendly": {
      "type": "object",
      "properties": {
        "connected": {
          "type": "boolean"
        },
        "scheduling_url": {
          "type": [
            "string",
            "null"
          ]
        },
        "has_webhook": {
          "type": "boolean"
        }
      },
      "required": [
        "connected",
        "scheduling_url",
        "has_webhook"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "google_calendar",
    "calendly"
  ],
  "additionalProperties": false
}

setter.knowledge.update

PATCH/v1/setter/knowledge/{knowledge_id}

Change a knowledge entry's title, content, or both.

Only the fields sent change. At least one of title and content is required.

Operation idsetter.knowledge.update
Scopessetter:write
Rate class`write`
IdempotencyNot applicable
KeysDeveloper keys
RepsA key restricted to reps sees only data of its own reps

Path parameters

NameTypeRequiredDescription
knowledge_idstringyes

Request body

FieldTypeRequiredDescription
contentstringnoUp to 8000 characters.. at most 8000 characters
titlestringno1 to 120 characters after trimming.

Response 200

FieldTypeRequiredDescription
contentstringyes
created_atdate-timeyes
iduuidyes
rep_iduuidyes
titlestringyes
updated_atdate-timeyes

Errors

StatusCodeWhen
400`VALIDATION_FAILED_400`A field is missing or malformed; fields names each one.
404`KNOWLEDGE_NOT_FOUND_404`The knowledge entry does not exist, or belongs to a rep outside the key's reps.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X PATCH "https://api.dmhero.ai/v1/setter/knowledge/string" \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "string",
  "content": "string"
}'
JSON Schema
Request body
{
  "type": "object",
  "properties": {
    "title": {
      "type": "string",
      "description": "1 to 120 characters after trimming."
    },
    "content": {
      "type": "string",
      "maxLength": 8000,
      "description": "Up to 8000 characters."
    }
  }
}
Response 200
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "rep_id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "title": {
      "type": "string"
    },
    "content": {
      "type": "string"
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
    }
  },
  "required": [
    "id",
    "rep_id",
    "title",
    "content",
    "created_at",
    "updated_at"
  ],
  "additionalProperties": false
}

setter.knowledge.delete

DELETE/v1/setter/knowledge/{knowledge_id}

Delete a knowledge entry.

Operation idsetter.knowledge.delete
Scopessetter:write
Rate class`write`
IdempotencyNot applicable
KeysDeveloper keys
DestructiveYes: it removes or stops something that cannot be restored by repeating the call
RepsA key restricted to reps sees only data of its own reps

Path parameters

NameTypeRequiredDescription
knowledge_idstringyes

Response 204

No body.

Errors

StatusCodeWhen
404`KNOWLEDGE_NOT_FOUND_404`The knowledge entry does not exist, or belongs to a rep outside the key's reps.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X DELETE "https://api.dmhero.ai/v1/setter/knowledge/string" \
  -H "Authorization: Bearer $DMHERO_API_KEY"

setter.persona.get

GET/v1/setter/persona

Read the persona (name, role, tone, style, language) of one or more reps.

The persona lives on each rep's live setter variant, the same record the app's Settings and AI Setter editor show. With several reps, mixed lists the fields they disagree on.

Operation idsetter.persona.get
Scopessetter:read
Rate class`read`
IdempotencyNot applicable
KeysDeveloper keys
RepsA key restricted to reps sees only data of its own reps

Query parameters

NameTypeRequiredDescription
rep_idsstring[]yesThe reps in scope: repeated, or as one comma-separated value. Every id must be one of the key's reps.. 1 to 50 items

Response 200

FieldTypeRequiredDescription
mixed("rep_name" | "rep_role" | "tone_text" | "style_text" | "language_text")[]yesFields whose value differs across the reps in scope.
rep_countintegeryes-9007199254740991 to 9007199254740991
rep_idsuuid[]yes
unconfigured_countintegeryesReps in scope with no live setter variant yet.. -9007199254740991 to 9007199254740991
valuesobjectyesPer field: the value the reps share, or the first rep's value when they differ.

Errors

StatusCodeWhen
400`VALIDATION_FAILED_400`A field is missing or malformed; fields names each one.
404`REP_NOT_FOUND_404`A rep does not exist in this workspace, is archived, or is outside the key's rep restriction.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl "https://api.dmhero.ai/v1/setter/persona?rep_ids=%5B%22string%22%5D" \
  -H "Authorization: Bearer $DMHERO_API_KEY"
JSON Schema
Response 200
{
  "type": "object",
  "properties": {
    "rep_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
      }
    },
    "values": {
      "type": "object",
      "properties": {
        "rep_name": {
          "type": "string"
        },
        "rep_role": {
          "type": "string"
        },
        "tone_text": {
          "type": "string"
        },
        "style_text": {
          "type": "string"
        },
        "language_text": {
          "type": "string"
        }
      },
      "required": [
        "rep_name",
        "rep_role",
        "tone_text",
        "style_text",
        "language_text"
      ],
      "additionalProperties": false,
      "description": "Per field: the value the reps share, or the first rep's value when they differ."
    },
    "mixed": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "rep_name",
          "rep_role",
          "tone_text",
          "style_text",
          "language_text"
        ]
      },
      "description": "Fields whose value differs across the reps in scope."
    },
    "rep_count": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991
    },
    "unconfigured_count": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991,
      "description": "Reps in scope with no live setter variant yet."
    }
  },
  "required": [
    "rep_ids",
    "values",
    "mixed",
    "rep_count",
    "unconfigured_count"
  ],
  "additionalProperties": false
}

setter.persona.set

PUT/v1/setter/persona

Write persona fields onto the live setter variant of each named rep.

Only the fields sent are written, onto every rep in rep_ids, so a field left out keeps each rep's own value. A rep with no live variant gets one created and published, as in the app. Every rep id is checked before anything is written: one foreign id and nothing changes.

Operation idsetter.persona.set
Scopessetter:write
Rate class`write`
IdempotencyNot applicable
KeysDeveloper keys
RepsA key restricted to reps sees only data of its own reps

Request body

FieldTypeRequiredDescription
rep_idsstring[]yesThe reps in scope: repeated, or as one comma-separated value. Every id must be one of the key's reps.. 1 to 50 items
language_textstringnoUp to 4000 characters.
rep_namestringnoUp to 4000 characters.
rep_rolestringnoUp to 4000 characters.
style_textstringnoUp to 4000 characters.
tone_textstringnoUp to 4000 characters.

Response 200

FieldTypeRequiredDescription
affected_countintegeryes-9007199254740991 to 9007199254740991
created_countintegeryesReps that had no live variant and got a new published one.. -9007199254740991 to 9007199254740991
mixed("rep_name" | "rep_role" | "tone_text" | "style_text" | "language_text")[]yesFields whose value differs across the reps in scope.
rep_countintegeryes-9007199254740991 to 9007199254740991
rep_idsuuid[]yes
unconfigured_countintegeryesReps in scope with no live setter variant yet.. -9007199254740991 to 9007199254740991
valuesobjectyesPer field: the value the reps share, or the first rep's value when they differ.

Errors

StatusCodeWhen
400`VALIDATION_FAILED_400`A field is missing or malformed; fields names each one.
404`REP_NOT_FOUND_404`A rep does not exist in this workspace, is archived, or is outside the key's rep restriction.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X PUT "https://api.dmhero.ai/v1/setter/persona" \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "rep_ids": [
    "3f6c2a9e-8b1d-4c7a-9e2f-5d4b3a2c1e0f"
  ],
  "tone_text": "Warm and direct, never pushy."
}'
JSON Schema
Request body
{
  "type": "object",
  "properties": {
    "rep_ids": {
      "minItems": 1,
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "The reps in scope: repeated, or as one comma-separated value. Every id must be one of the key's reps."
    },
    "rep_name": {
      "type": "string",
      "description": "Up to 4000 characters."
    },
    "rep_role": {
      "type": "string",
      "description": "Up to 4000 characters."
    },
    "tone_text": {
      "type": "string",
      "description": "Up to 4000 characters."
    },
    "style_text": {
      "type": "string",
      "description": "Up to 4000 characters."
    },
    "language_text": {
      "type": "string",
      "description": "Up to 4000 characters."
    }
  },
  "required": [
    "rep_ids"
  ]
}
Response 200
{
  "type": "object",
  "properties": {
    "rep_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
      }
    },
    "values": {
      "type": "object",
      "properties": {
        "rep_name": {
          "type": "string"
        },
        "rep_role": {
          "type": "string"
        },
        "tone_text": {
          "type": "string"
        },
        "style_text": {
          "type": "string"
        },
        "language_text": {
          "type": "string"
        }
      },
      "required": [
        "rep_name",
        "rep_role",
        "tone_text",
        "style_text",
        "language_text"
      ],
      "additionalProperties": false,
      "description": "Per field: the value the reps share, or the first rep's value when they differ."
    },
    "mixed": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "rep_name",
          "rep_role",
          "tone_text",
          "style_text",
          "language_text"
        ]
      },
      "description": "Fields whose value differs across the reps in scope."
    },
    "rep_count": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991
    },
    "unconfigured_count": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991,
      "description": "Reps in scope with no live setter variant yet."
    },
    "affected_count": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991
    },
    "created_count": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991,
      "description": "Reps that had no live variant and got a new published one."
    }
  },
  "required": [
    "rep_ids",
    "values",
    "mixed",
    "rep_count",
    "unconfigured_count",
    "affected_count",
    "created_count"
  ],
  "additionalProperties": false
}

setter.test

POST/v1/setter/test

Run the AI Setter on a typed thread with an inline configuration and get its next reply.

The Test Chat sandbox: nothing is saved, nothing is sent, no DM limit is used. The reply runs through the same reaction gate as the live setter; with goal_tool google_calendar it reads the workspace's free/busy and answers what the reply's booking would have done, marked simulated (no event, no hold). Each call is one or two model calls and is metered like the app's Test Chat. At most 30 calls a minute per key. A thread needs at least one prospect message.

Operation idsetter.test
Scopessetter:write
Rate class`heavy`
IdempotencyNot applicable
KeysDeveloper keys
RepsA key restricted to reps sees only data of its own reps

Request body

FieldTypeRequiredDescription
rep_idstringyesThe rep whose knowledge base and timezone the turn uses.
threadobject[]yes1 to 100 items
configobjectnoThe same fields as a setter variant, validated by the app's editor rules. Omitted fields take the defaults.
leadobjectno

Response 200

FieldTypeRequiredDescription
bubblesstring[]yes
messagestringyesThe reply text, exactly what the live setter would send.
proposed_reactionstring | nullyes
reactionobject | nullyes
reaction_blocked_bystring | nullyes
calendarobjectnoOnly with goal_tool google_calendar.

Errors

StatusCodeWhen
400`VALIDATION_FAILED_400`A field is missing or malformed; fields names each one.
403`GOOGLE_CALENDAR_NOT_ENABLED_403`Google Calendar booking is not enabled for this organization yet.
404`REP_NOT_FOUND_404`A rep does not exist in this workspace, is archived, or is outside the key's rep restriction.
409`CALENDAR_NOT_CONNECTED_409`goal_tool is google_calendar and the workspace has no healthy Google Calendar connection.
429`SETTER_TEST_RATE_LIMITED_429`More than 30 Test Chat calls in a minute for this key (rotations share the count).
502`SETTER_TEST_FAILED_502`The reply could not be generated: a model, calendar or storage call failed while answering the turn. Retry later.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X POST "https://api.dmhero.ai/v1/setter/test" \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "rep_id": "string",
  "thread": [
    {
      "from_prospect": true,
      "text": "string"
    }
  ]
}'
JSON Schema
Request body
{
  "type": "object",
  "properties": {
    "rep_id": {
      "type": "string",
      "description": "The rep whose knowledge base and timezone the turn uses."
    },
    "config": {
      "type": "object",
      "properties": {
        "goal_text": {
          "type": "string"
        },
        "goal_link": {
          "type": [
            "string",
            "null"
          ]
        },
        "goal_tool": {
          "description": "manual, calendly, link or google_calendar.",
          "type": "string"
        },
        "goal_link_status": {
          "type": "string"
        },
        "key_elements_text": {
          "type": "string"
        },
        "avoid_text": {
          "type": "string"
        },
        "offer_text": {
          "type": "string"
        },
        "icp_text": {
          "type": "string"
        },
        "qualifying_text": {
          "type": "string"
        },
        "disqualify_text": {
          "type": "string"
        },
        "tone_text": {
          "type": "string"
        },
        "style_text": {
          "type": "string"
        },
        "language_text": {
          "type": "string"
        },
        "phrases_text": {
          "type": "string"
        },
        "rep_name": {
          "type": "string"
        },
        "rep_role": {
          "type": "string"
        },
        "message_style": {
          "type": "string"
        },
        "objection_mode": {
          "type": "string"
        },
        "few_shot": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "prospect": {
                "type": "string"
              },
              "reply": {
                "type": "string"
              }
            },
            "required": [
              "prospect",
              "reply"
            ]
          }
        },
        "objections": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "objection": {
                "type": "string"
              },
              "approach": {
                "type": "string"
              }
            },
            "required": [
              "objection",
              "approach"
            ]
          }
        },
        "reaction_frequency": {
          "type": "string"
        },
        "reaction_emojis": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "reaction_rules": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "emoji": {
                "type": "string"
              },
              "when": {
                "type": "string"
              }
            },
            "required": [
              "emoji",
              "when"
            ]
          }
        },
        "booking_config": {
          "type": "object",
          "properties": {
            "duration_min": {
              "type": "number"
            },
            "buffer_min": {
              "type": "number"
            },
            "working_hours": {
              "description": "Per weekday, up to 4 [\"HH:MM\", \"HH:MM\"] intervals.",
              "type": "object",
              "properties": {
                "mon": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "string"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "tue": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "string"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "wed": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "string"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "thu": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "string"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "fri": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "string"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "sat": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "string"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "sun": {
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "string"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                }
              }
            },
            "min_notice_min": {
              "type": "number"
            },
            "allow_same_day": {
              "type": "boolean"
            },
            "horizon_days": {
              "type": "number"
            },
            "max_per_day": {
              "type": [
                "number",
                "null"
              ]
            },
            "meeting_form": {
              "type": "string",
              "enum": [
                "meet",
                "phone"
              ]
            },
            "event_title": {
              "type": "string"
            },
            "event_description": {
              "type": "string"
            },
            "prospect_tz_mode": {
              "type": "string",
              "enum": [
                "campaign",
                "fixed"
              ]
            },
            "prospect_tz": {
              "type": [
                "string",
                "null"
              ]
            },
            "target_calendar_id": {
              "type": "string"
            },
            "busy_calendar_ids": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "description": "Read only when goal_tool is google_calendar. Omitted fields take the defaults."
        }
      },
      "description": "The same fields as a setter variant, validated by the app's editor rules. Omitted fields take the defaults."
    },
    "thread": {
      "minItems": 1,
      "maxItems": 100,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "from_prospect": {
            "type": "boolean"
          },
          "text": {
            "type": "string",
            "maxLength": 4000
          },
          "our_reaction": {
            "description": "A reaction an earlier answer approved on this prospect bubble.",
            "type": [
              "string",
              "null"
            ]
          },
          "proposals": {
            "description": "On our bubble: the times an earlier answer proposed.",
            "maxItems": 5,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "starts_at": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                },
                "label": {
                  "type": "string"
                }
              },
              "required": [
                "starts_at",
                "label"
              ]
            }
          }
        },
        "required": [
          "from_prospect",
          "text"
        ]
      }
    },
    "lead": {
      "type": "object",
      "properties": {
        "name": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 200
            },
            {
              "type": "null"
            }
          ]
        },
        "niche": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 200
            },
            {
              "type": "null"
            }
          ]
        },
        "handle": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 100
            },
            {
              "type": "null"
            }
          ]
        }
      }
    }
  },
  "required": [
    "rep_id",
    "thread"
  ]
}
Response 200
{
  "type": "object",
  "properties": {
    "message": {
      "type": "string",
      "description": "The reply text, exactly what the live setter would send."
    },
    "bubbles": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "reaction": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "emoji": {
              "type": "string"
            },
            "target_index": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          },
          "required": [
            "emoji",
            "target_index"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    },
    "reaction_blocked_by": {
      "type": [
        "string",
        "null"
      ]
    },
    "proposed_reaction": {
      "type": [
        "string",
        "null"
      ]
    },
    "calendar": {
      "description": "Only with goal_tool google_calendar.",
      "type": "object",
      "properties": {
        "scheduling": {
          "type": "object",
          "properties": {
            "phase": {
              "type": "string"
            },
            "tz": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          "required": [
            "phase",
            "tz"
          ],
          "additionalProperties": false
        },
        "ranges_block": {
          "type": [
            "string",
            "null"
          ]
        },
        "proposals": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "starts_at": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
              },
              "label": {
                "type": "string"
              },
              "valid": {
                "type": "boolean"
              }
            },
            "required": [
              "starts_at",
              "label",
              "valid"
            ],
            "additionalProperties": false
          }
        },
        "booking": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "email": {
                  "type": "string"
                },
                "simulated": {
                  "type": "boolean",
                  "const": true
                },
                "valid": {
                  "type": "boolean"
                },
                "reason": {
                  "anyOf": [
                    {
                      "type": "string",
                      "enum": [
                        "outside_rules",
                        "invalid_email",
                        "calendar_unavailable"
                      ]
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "required": [
                "label",
                "email",
                "simulated",
                "valid",
                "reason"
              ],
              "additionalProperties": false
            },
            {
              "type": "null"
            }
          ]
        },
        "directives_malformed": {
          "type": "boolean"
        },
        "calendar_unavailable": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "scheduling",
        "ranges_block",
        "proposals",
        "booking",
        "directives_malformed",
        "calendar_unavailable"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "message",
    "bubbles",
    "reaction",
    "reaction_blocked_by",
    "proposed_reaction"
  ],
  "additionalProperties": false
}
AI Setter | DM Hero Developers