# Redraft Email Batch Recipients

`POST /v1/email/batches/{batch_id}/redraft`

Draft rows again from scratch. **Each one runs the task and is billed again.**

`selection` is `failed` (drafting failed), `stale_version` (drafted by an
older published version of the task), `not_sent`, or `all` — which names
every row it refuses. Rows already sent are never redrafted; a `queued` one
is, and its send takes the new draft.

This revives a batch that had finished drafting, and a person's edited cells
survive unless you pass `clear_overrides` — and are what the task is given.
Refused on a canceled batch, whose rows can never draft again.

Authenticate with `Authorization: Bearer $TALQING_API_KEY`. Errors use the shared envelope: https://docs.talqing.com/api-reference/errors.md

## OpenAPI

```json
{
 "openapi":"3.1.0",
 "servers":[
  {
   "description":"Talqing API",
   "url":"https://api.talqing.com"
  }
 ],
 "paths":{
  "/v1/email/batches/{batch_id}/redraft":{
   "post":{
    "description":"Draft rows again from scratch. **Each one runs the task and is billed again.**\n\n`selection` is `failed` (drafting failed), `stale_version` (drafted by an\nolder published version of the task), `not_sent`, or `all` \u2014 which names\nevery row it refuses. Rows already sent are never redrafted; a `queued` one\nis, and its send takes the new draft.\n\nThis revives a batch that had finished drafting, and a person's edited cells\nsurvive unless you pass `clear_overrides` \u2014 and are what the task is given.\nRefused on a canceled batch, whose rows can never draft again.",
    "operationId":"email.batches.recipients.redraft",
    "parameters":[
     {
      "in":"path",
      "name":"batch_id",
      "required":true,
      "schema":{
       "format":"uuid",
       "title":"Batch Id",
       "type":"string"
      }
     }
    ],
    "requestBody":{
     "content":{
      "application/json":{
       "schema":{
        "$ref":"#/components/schemas/RedraftRequest"
       }
      }
     },
     "required":true
    },
    "responses":{
     "200":{
      "content":{
       "application/json":{
        "schema":{
         "$ref":"#/components/schemas/RecipientActionResponse"
        }
       }
      },
      "description":"Successful Response"
     },
     "400":{
      "$ref":"#/components/responses/BadRequest"
     },
     "401":{
      "$ref":"#/components/responses/Unauthorized"
     },
     "403":{
      "$ref":"#/components/responses/Forbidden"
     },
     "404":{
      "$ref":"#/components/responses/NotFound"
     },
     "409":{
      "$ref":"#/components/responses/Conflict"
     },
     "422":{
      "$ref":"#/components/responses/ValidationFailed"
     },
     "default":{
      "$ref":"#/components/responses/Error"
     }
    },
    "security":[
     {
      "BearerAuth":[]
     },
     {
      "SessionCookie":[]
     }
    ],
    "summary":"Redraft Email Batch Recipients",
    "tags":[
     "email"
    ]
   }
  }
 },
 "components":{
  "responses":{
   "BadRequest":{
    "content":{
     "application/json":{
      "schema":{
       "$ref":"#/components/schemas/ErrorResponse"
      }
     }
    },
    "description":"Well-formed, but rejected by a rule; `detail.errors` lists each problem."
   },
   "Conflict":{
    "content":{
     "application/json":{
      "schema":{
       "$ref":"#/components/schemas/ErrorResponse"
      }
     }
    },
    "description":"The resource's current state forbids this \u2014 a name already taken, a job already running."
   },
   "Error":{
    "content":{
     "application/json":{
      "schema":{
       "$ref":"#/components/schemas/ErrorResponse"
      }
     }
    },
    "description":"Unexpected error. Every error this API returns carries this body."
   },
   "Forbidden":{
    "content":{
     "application/json":{
      "schema":{
       "$ref":"#/components/schemas/ErrorResponse"
      }
     }
    },
    "description":"Authenticated, but this organization role may not perform the operation."
   },
   "NotFound":{
    "content":{
     "application/json":{
      "schema":{
       "$ref":"#/components/schemas/ErrorResponse"
      }
     }
    },
    "description":"No such resource in this organization."
   },
   "Unauthorized":{
    "content":{
     "application/json":{
      "schema":{
       "$ref":"#/components/schemas/ErrorResponse"
      }
     }
    },
    "description":"Missing credential, or one that is revoked or no longer a member of this organization."
   },
   "ValidationFailed":{
    "content":{
     "application/json":{
      "schema":{
       "$ref":"#/components/schemas/ErrorResponse"
      }
     }
    },
    "description":"The request did not match this operation's schema; `detail.errors` lists each field."
   }
  },
  "schemas":{
   "ErrorBody":{
    "description":"The structured half of our error contract: a human `message` plus a list\nof individual `errors` (used wherever we surface many problems at once,\nincluding tool publish, op-tree checks, and request validation). The global\nexception handlers normalize every API error to\n`{detail: {message, errors, code}}`, so SDKs can parse one shape consistently.",
    "properties":{
     "code":{
      "anyOf":[
       {
        "type":"string"
       },
       {
        "type":"null"
       }
      ],
      "default":null,
      "description":"A stable identifier for this error, when it has one.",
      "title":"Code"
     },
     "errors":{
      "items":{
       "type":"string"
      },
      "title":"Errors",
      "type":"array"
     },
     "message":{
      "title":"Message",
      "type":"string"
     }
    },
    "required":[
     "message",
     "errors"
    ],
    "title":"ErrorBody",
    "type":"object"
   },
   "ErrorResponse":{
    "description":"The body of every error response, at every status code.",
    "properties":{
     "detail":{
      "$ref":"#/components/schemas/ErrorBody"
     }
    },
    "required":[
     "detail"
    ],
    "title":"ErrorResponse",
    "type":"object"
   },
   "RecipientActionResponse":{
    "description":"Skip-and-report, never a partial silent accept.",
    "properties":{
     "affected":{
      "title":"Affected",
      "type":"integer"
     },
     "rejected":{
      "items":{
       "$ref":"#/components/schemas/RejectedRecipient"
      },
      "title":"Rejected",
      "type":"array"
     }
    },
    "required":[
     "affected",
     "rejected"
    ],
    "title":"RecipientActionResponse",
    "type":"object"
   },
   "RedraftRequest":{
    "additionalProperties":false,
    "description":"Draft these rows again, from scratch.\n\nOne verb for \"write this row again\", whatever put it in the state it is in \u2014\na failed attempt, a prompt that has since improved, a draft nobody liked.\nFour selections, and they differ in what they REFUSE as much as in what they\nmove, because a redraft discards a draft the tenant has already paid for:\n\n- ``all`` \u2014 every row in the batch. Rows already sent or mid-send come back in\n  ``rejected``, by name, so a bulk press cannot quietly do less than it said.\n- ``failed`` \u2014 rows whose drafting failed.\n- ``not_sent`` \u2014 every row that has not left, with nothing rejected.\n- ``stale_version`` \u2014 rows drafted by a task version older than the one\n  published now. The selection that makes \"watch the output, improve the\n  task, publish, redraft the rest\" a workflow rather than a wish.",
    "properties":{
     "clear_overrides":{
      "default":false,
      "description":"Also discard the cells a person edited by hand. Off by default.",
      "title":"Clear Overrides",
      "type":"boolean"
     },
     "recipient_ids":{
      "anyOf":[
       {
        "items":{
         "format":"uuid",
         "type":"string"
        },
        "type":"array"
       },
       {
        "type":"null"
       }
      ],
      "title":"Recipient Ids"
     },
     "selection":{
      "anyOf":[
       {
        "enum":[
         "all",
         "failed",
         "not_sent",
         "stale_version"
        ],
        "type":"string"
       },
       {
        "type":"null"
       }
      ],
      "title":"Selection"
     }
    },
    "title":"RedraftRequest",
    "type":"object"
   },
   "RejectedRecipient":{
    "properties":{
     "reason":{
      "title":"Reason",
      "type":"string"
     },
     "recipient_id":{
      "format":"uuid",
      "title":"Recipient Id",
      "type":"string"
     },
     "row_number":{
      "title":"Row Number",
      "type":"integer"
     }
    },
    "required":[
     "recipient_id",
     "row_number",
     "reason"
    ],
    "title":"RejectedRecipient",
    "type":"object"
   }
  }
 }
}
```
