Create writing style
Add a new named voice configuration: for content (articles) or for one social channel (Reddit, LinkedIn). Refuses past 10 styles in the same scope, and refuses a name already used in that scope — both match the app.
POST /brands/{brand_id}/writing-stylesAuthorization
| Header | Type | Required |
|---|---|---|
Authorization | Bearer asky_sk_… | required |
Idempotency-Key | string | required on every write. See Idempotency |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
brand_id | uuid | required | From List brands |
Body parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
surface | string | required | content or social |
channel | string | required when surface is social | reddit or linkedin. Must be omitted when surface is content |
name | string | required | 1 to 60 characters. Must be unique within this scope (case-insensitive) |
tone_of_voice | object | optional | { presets?: string[], custom_tones?: string[], description?: string }. presets entries must exactly match one of Expert, Conversational, Confident, Educational, Bold, Empathetic, Direct, Approachable, Storytelling — anything else belongs in custom_tones, which is free text |
writing_rules | object | optional | { always_do?: string[], never_do?: string[] } |
heading_case_style | string | optional | sentence or title. Content styles only — rejected on a social style |
translation_formality | string | optional | default, prefer_more or prefer_less. Content styles only |
competitor_statistics_mode | string | optional | ask, include or exclude. Content styles only |
english_variant | string | optional | us or uk. Content styles only — a social style’s spelling preference goes in language_overrides.en instead |
language_overrides | object | optional | Social styles only. Keyed by ISO 639-1 code, e.g. {"de": {"formality": "prefer_more", "nuance": "...", "always_do": [], "never_do": [], "english_variant": null}} |
is_default | boolean | optional | Make this the scope’s default immediately after creating it |
Request
cURL
curl --request POST \
--url 'https://api.askylabs.com/v1/brands/242546de-4cee-4a7d-952e-f6aa60c63ef8/writing-styles' \
--header 'Authorization: Bearer <api-key>' \
--header 'Idempotency-Key: 9c2e5f1a-3b7d-4a6e-8c1f-2d5b7a9e6f30' \
--header 'Content-Type: application/json' \
--data '{
"surface": "social",
"channel": "linkedin",
"name": "LinkedIn Professional"
}'Response
200
{
"data": {
"id": "8c082c21-a2eb-4c0f-bcd9-d58097a48e45",
"name": "LinkedIn Professional",
"surface": "social",
"channel": "linkedin",
"is_default": false,
"sort_order": 0,
"tone_of_voice": { "presets": [], "custom_tones": [], "description": "" },
"writing_rules": { "always_do": [], "never_do": [] },
"heading_case_style": "sentence",
"translation_formality": null,
"competitor_statistics_mode": null,
"english_variant": null,
"language_overrides": {},
"tone_generation_status": null,
"created_at": "2026-08-29T02:15:00.000Z",
"updated_at": "2026-08-29T02:15:00.000Z"
},
"request_id": "req_7c9e1f3a4b2d46f08a1c"
}Response fields
Same shape as Get writing style’s data.
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_request | channel missing when surface=social, channel present when surface=content, a content-only field set on a social style, language_overrides set on a content style, or another malformed field. The message names it |
| 401 | invalid_token | The key is missing, malformed, or does not exist |
| 401 | token_expired | The key passed its expiry date |
| 401 | token_revoked | The key was revoked |
| 404 | not_found | The brand does not exist, or this key is not allowed to reach it |
| 409 | conflict | This scope already has 10 styles, or a style with this name already exists in this scope |
| 429 | rate_limited | Over 60 requests per minute on write endpoints |
Notes
surface and channel cannot be changed after creation. There is no update path for either —
create a new style and delete the old one if you need to move a configuration.
channel is limited to reddit and linkedin. The underlying schema also allows quora and
hackernews, but neither has any app support yet, so the API does not expose them either.
A style with no fields set beyond name is not useless. It falls back to the DB defaults (an
empty tone/rules, heading_case_style: "sentence"), the same starting point a new style gets in
the app before anyone edits it.