Kenso

Email copy grades

Grade email or LinkedIn copy before you send it.

AI1 endpointKen-Version: 2026-11-02AuthenticationWorkspacesErrors

channel is email (default), linkedin_connection or linkedin_message; any other value is 400 on channel. Email sends the text to Jev using the client-system copy questions and returns those scores plus an overall band (keep, rewrite, start_over). Callers prefix a follow-up themselves. A LinkedIn step returns five 0-10 bars (quick_read, cta, easy, weird_word, personal), their mean as the score, keep at 7.5 or more with no weird_word alarm, rewrite at 5.5 or more, else start_over; a connection note over 300 characters fails easy. A saved grade for subjectKey and channel is returned even when the copy changed. refresh: true grades the new copy and replaces that row, and needs campaigns edit (403 otherwise). Requires campaigns view and Ask. Each call takes one unit of the workspace's aiEmailCopyGrades quota (20 a minute, 500 a day, every caller kind): past it, 429 quota_exceeded with Retry-After. campaignId is optional: a recruiting campaign of the workspace grades with the recruiting rubric and saves under its own key, so its subjectKey is at most 149 characters (129 on linkedin_connection, 132 on linkedin_message); another workspace's campaign is 404. A subjectKey cannot start with recruiting:.

Parameters

Name
In
Type
Required
Description
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Request body

application/json, optional.

Field
Type
Required
Description
copy
string
optional
subjectKey
string
optional
refresh
boolean
optional
channel
string
optional
The sequence step the copy is for: email (the default when omitted), linkedin_connection or linkedin_message.
campaignId
integer (int64)
optional
The campaign the copy is for. A recruiting campaign grades with the recruiting rubric and keeps its own saved grade. Omit it (or send 0) to grade as before. A campaign of another workspace answers 404.

Response 200

data is a EmailCopyGradeModel.

Field
Type
Description
channel
string
The channel that was graded: email, linkedin_connection or linkedin_message.
copyHash
string
gradedAt
string (date-time)
fromSavedGrade
boolean
overall
EmailCopyGradeOverallModel
general
EmailCopyGradeGeneralModel
questions
array of EmailCopyGradeQuestionModel
criteria
array of EmailCopyGradeCriterionModel
Request
curl -X POST "https://api.ken.so/v1/email-copy-grades" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 2026-11-02" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
  "copy": "string",
  "subjectKey": "string",
  "refresh": true,
  "channel": "string",
  "campaignId": 812
}'
Response 200
{
  "success": true,
  "data": {
    "channel": "string",
    "copyHash": "string",
    "gradedAt": "2026-09-23T15:02:11Z",
    "fromSavedGrade": true,
    "overall": {
      "score": 0.5,
      "band": "string",
      "summary": "string",
      "alarmQuestionIds": [
        "string"
      ]
    },
    "general": {
      "score": 0.5,
      "label": "string"
    },
    "questions": [
      {
        "id": "string",
        "label": "string",
        "kind": "string",
        "blurb": "string",
        "alarm": true,
        "score": 1,
        "yes": true,
        "probability": 0.5
      }
    ],
    "criteria": [
      {
        "key": "string",
        "label": "string",
        "kind": "string",
        "summary": "string",
        "score": 1,
        "yes": true,
        "probability": 0.5
      }
    ]
  }
}