Skip to Content
APIEndpointsCreate writing style

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-styles

Authorization

HeaderTypeRequired
AuthorizationBearer asky_sk_…required
Idempotency-Keystringrequired on every write. See Idempotency

Path parameters

ParameterTypeRequiredDescription
brand_iduuidrequiredFrom List brands

Body parameters

ParameterTypeRequiredDescription
surfacestringrequiredcontent or social
channelstringrequired when surface is socialreddit or linkedin. Must be omitted when surface is content
namestringrequired1 to 60 characters. Must be unique within this scope (case-insensitive)
tone_of_voiceobjectoptional{ 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_rulesobjectoptional{ always_do?: string[], never_do?: string[] }
heading_case_stylestringoptionalsentence or title. Content styles only — rejected on a social style
translation_formalitystringoptionaldefault, prefer_more or prefer_less. Content styles only
competitor_statistics_modestringoptionalask, include or exclude. Content styles only
english_variantstringoptionalus or uk. Content styles only — a social style’s spelling preference goes in language_overrides.en instead
language_overridesobjectoptionalSocial styles only. Keyed by ISO 639-1 code, e.g. {"de": {"formality": "prefer_more", "nuance": "...", "always_do": [], "never_do": [], "english_variant": null}}
is_defaultbooleanoptionalMake this the scope’s default immediately after creating it

Request

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

{ "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

StatusCodeWhen
400invalid_requestchannel 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
401invalid_tokenThe key is missing, malformed, or does not exist
401token_expiredThe key passed its expiry date
401token_revokedThe key was revoked
404not_foundThe brand does not exist, or this key is not allowed to reach it
409conflictThis scope already has 10 styles, or a style with this name already exists in this scope
429rate_limitedOver 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.

Last updated on