Skip to content

Stylists Endpoints

Stylists API endpoints.


Overview

Method Endpoint Description
GET /api/v1/stylists/ Read Stylists
POST /api/v1/stylists/ Create Stylist
GET /api/v1/stylists/{id} Read Stylist
PUT /api/v1/stylists/{id} Update Stylist
DELETE /api/v1/stylists/{id} Delete Stylist

API Reference

Sartiq Backend Server - Stylists 0.1.0

stylists


GET /api/v1/stylists/

Read Stylists

Description

Retrieve stylists. Optionally filter by owner and public status.

When organization_id query param is provided, returns stylists belonging to that organization. Without organization_id, returns only personal stylists (not belonging to any organization).

Input parameters

Parameter In Type Default Nullable Description
OAuth2PasswordBearer header string N/A No
limit query integer 100 No
organization_id query No
owner_id query No
public query No
skip query integer 0 No

Responses

{
    "id": "9baf3b97-156d-48fe-be22-e3850390bd8a",
    "created_at": "2022-04-13T15:42:05.901Z",
    "updated_at": "2022-04-13T15:42:05.901Z",
    "data": [
        {
            "id": "627ca618-918f-4c00-a7c5-13c95bd1ef4a",
            "created_at": "2022-04-13T15:42:05.901Z",
            "updated_at": "2022-04-13T15:42:05.901Z",
            "name": "string",
            "styling_template_values": {
                "AESTHETIC": "preppy-collegiate",
                "COLOR_RULES": "BLACKBEAN/BLACK → black\nNAVY/DARKBLUE → navy...",
                "FILLER_SPECIFIC_NOTES": "Real sneakers exist in catalog, use these first...",
                "LAYERING_RULES": "Max 3-4 colors per look. Preppy combos encouraged...",
                "OPTIONALITY_RULES": "Upper_layer optional if mid_layer provides enough visual interest...",
                "SELECTION_LOGIC": "The core product MUST ALWAYS appear in the items array...",
                "STYLING_DNA": "Silhouette: preppy-collegiate. Layering is key..."
            },
            "public": true,
            "owner_id": "9b95fc0a-262a-491e-9bf9-cc7b19084360",
            "candidate_scope_rules": [
                "brand"
            ],
            "underpinnings_query_template": null,
            "organization_id": null
        }
    ],
    "count": 0
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id"
        },
        "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
        },
        "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At"
        },
        "data": {
            "items": {
                "$ref": "#/components/schemas/StylistPublic"
            },
            "type": "array",
            "title": "Data"
        },
        "count": {
            "type": "integer",
            "title": "Count"
        }
    },
    "type": "object",
    "required": [
        "data",
        "count"
    ],
    "title": "StylistsPublic"
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string",
            "input": null,
            "ctx": {}
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

POST /api/v1/stylists/

Create Stylist

Description

Create new stylist.

Admins can specify owner_id to create stylists for other users. Non-admins will get an error if they try to set owner_id.

Input parameters

Parameter In Type Default Nullable Description
OAuth2PasswordBearer header string N/A No
organization_id query No

Request body

{
    "name": "string",
    "styling_template_values": {
        "AESTHETIC": "preppy-collegiate",
        "COLOR_RULES": "BLACKBEAN/BLACK → black\nNAVY/DARKBLUE → navy...",
        "FILLER_SPECIFIC_NOTES": "Real sneakers exist in catalog, use these first...",
        "LAYERING_RULES": "Max 3-4 colors per look. Preppy combos encouraged...",
        "OPTIONALITY_RULES": "Upper_layer optional if mid_layer provides enough visual interest...",
        "SELECTION_LOGIC": "The core product MUST ALWAYS appear in the items array...",
        "STYLING_DNA": "Silhouette: preppy-collegiate. Layering is key..."
    },
    "public": true,
    "owner_id": null,
    "candidate_scope_rules": [
        "brand"
    ],
    "underpinnings_query_template": null,
    "organization_id": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "properties": {
        "name": {
            "type": "string",
            "maxLength": 255,
            "title": "Name",
            "description": "Name of the stylist"
        },
        "styling_template_values": {
            "$ref": "#/components/schemas/StylistTemplateValuesSchema",
            "description": "Template values for AI prompt composition"
        },
        "public": {
            "type": "boolean",
            "title": "Public",
            "description": "Whether the stylist is publicly accessible",
            "default": false
        },
        "owner_id": {
            "anyOf": [
                {
                    "type": "string",
                    "format": "uuid"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Owner Id",
            "description": "Owner user ID. Only admins can set this. If not provided, defaults to current user."
        },
        "candidate_scope_rules": {
            "items": {
                "$ref": "#/components/schemas/StylistScopeRule"
            },
            "type": "array",
            "title": "Candidate Scope Rules",
            "description": "Which predicates narrow the candidate pool, compared against the product being shot. Each is NULL-permissive: an unclassified product stays eligible. Gender, age band and slot compatibility always apply and are not listed here."
        },
        "underpinnings_query_template": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Underpinnings Query Template",
            "description": "Custom WHERE clause for product filtering. Admin-only. \nAvailable wildcards (use :wildcard syntax for SQLAlchemy bound parameters):\n- :core_id (UUID) - Core product ID\n- :core_brand (string) - Core product brand\n- :core_brand_collection (string) - Core product brand collection\n- :core_gender (string) - Core product gender (MALE/FEMALE/UNISEX)\n- :core_season (string) - Core product season\n- :core_year (int) - Core product year\n- :core_in_store_date (datetime) - Core product in-store date\n- :core_product_family (string) - Core product family (APPAREL/FOOTWEAR/ACCESSORIES/BEAUTY)\n- :core_product_type (string) - Core product type\n- :core_age_class (string) - Core product age class\n- :core_owner_id (UUID) - Core product owner ID\n- :core_organization_id (UUID) - Core product organization ID\n- :core_theme (string) - Core product theme\n- :subject_gender (string) - Subject's gender (MALE/FEMALE/OTHER)\n\nSupported expression grammar: AND/OR/NOT, parentheses, =/!=/<>/</<=/>/>=,\nIS NULL/IS NOT NULL, IN/NOT IN, LIKE/ILIKE, literals, and the lower(), upper(),\ntrim(), and coalesce() functions. Allowed fields are id, brand, brand_collection,\ngender, season, year, in_store_date, age_class, master_item_code, color_name,\nowner_id, organization_id, theme, product_type, and product_family (optionally\nqualified by product/p, ptr, or pf as shown below). Statements, subqueries,\ncomments, and unknown fields/functions/parameters are rejected.\n\nExample: \"lower(trim(product.brand)) = lower(trim(:core_brand)) AND product.season = :core_season\"\n(normalize brand with lower(trim(...)) on both sides so stored whitespace/casing still matches)\n"
        },
        "organization_id": {
            "anyOf": [
                {
                    "type": "string",
                    "format": "uuid"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Organization Id",
            "description": "Organization this stylist belongs to"
        }
    },
    "type": "object",
    "required": [
        "name",
        "styling_template_values"
    ],
    "title": "StylistCreate",
    "description": "Schema for creating a new stylist."
}

Responses

{
    "id": "2f3408e4-9766-42a5-b5be-39109208bdff",
    "created_at": "2022-04-13T15:42:05.901Z",
    "updated_at": "2022-04-13T15:42:05.901Z",
    "name": "string",
    "styling_template_values": {
        "AESTHETIC": "preppy-collegiate",
        "COLOR_RULES": "BLACKBEAN/BLACK → black\nNAVY/DARKBLUE → navy...",
        "FILLER_SPECIFIC_NOTES": "Real sneakers exist in catalog, use these first...",
        "LAYERING_RULES": "Max 3-4 colors per look. Preppy combos encouraged...",
        "OPTIONALITY_RULES": "Upper_layer optional if mid_layer provides enough visual interest...",
        "SELECTION_LOGIC": "The core product MUST ALWAYS appear in the items array...",
        "STYLING_DNA": "Silhouette: preppy-collegiate. Layering is key..."
    },
    "public": true,
    "owner_id": "60e2e7d2-13e0-4bae-bcd2-1ef7b89f1e7e",
    "candidate_scope_rules": [
        "brand"
    ],
    "underpinnings_query_template": null,
    "organization_id": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id"
        },
        "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
        },
        "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At"
        },
        "name": {
            "type": "string",
            "title": "Name"
        },
        "styling_template_values": {
            "$ref": "#/components/schemas/StylistTemplateValuesSchema"
        },
        "public": {
            "type": "boolean",
            "title": "Public"
        },
        "owner_id": {
            "type": "string",
            "format": "uuid",
            "title": "Owner Id"
        },
        "candidate_scope_rules": {
            "items": {
                "$ref": "#/components/schemas/StylistScopeRule"
            },
            "type": "array",
            "title": "Candidate Scope Rules",
            "default": []
        },
        "underpinnings_query_template": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Underpinnings Query Template"
        },
        "organization_id": {
            "anyOf": [
                {
                    "type": "string",
                    "format": "uuid"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Organization Id"
        }
    },
    "type": "object",
    "required": [
        "id",
        "created_at",
        "updated_at",
        "name",
        "styling_template_values",
        "public",
        "owner_id"
    ],
    "title": "StylistPublic",
    "description": "Schema for stylist public response."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string",
            "input": null,
            "ctx": {}
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/stylists/{id}

Read Stylist

Description

Get stylist by ID.

Input parameters

Parameter In Type Default Nullable Description
OAuth2PasswordBearer header string N/A No
id path string No
organization_id query No

Responses

{
    "id": "a45a1e11-6cae-449e-bb84-7e97697bc0e0",
    "created_at": "2022-04-13T15:42:05.901Z",
    "updated_at": "2022-04-13T15:42:05.901Z",
    "name": "string",
    "styling_template_values": {
        "AESTHETIC": "preppy-collegiate",
        "COLOR_RULES": "BLACKBEAN/BLACK → black\nNAVY/DARKBLUE → navy...",
        "FILLER_SPECIFIC_NOTES": "Real sneakers exist in catalog, use these first...",
        "LAYERING_RULES": "Max 3-4 colors per look. Preppy combos encouraged...",
        "OPTIONALITY_RULES": "Upper_layer optional if mid_layer provides enough visual interest...",
        "SELECTION_LOGIC": "The core product MUST ALWAYS appear in the items array...",
        "STYLING_DNA": "Silhouette: preppy-collegiate. Layering is key..."
    },
    "public": true,
    "owner_id": "ae7795c2-5fc2-4d00-8d64-ef9639f790dd",
    "candidate_scope_rules": [
        "brand"
    ],
    "underpinnings_query_template": null,
    "organization_id": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id"
        },
        "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
        },
        "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At"
        },
        "name": {
            "type": "string",
            "title": "Name"
        },
        "styling_template_values": {
            "$ref": "#/components/schemas/StylistTemplateValuesSchema"
        },
        "public": {
            "type": "boolean",
            "title": "Public"
        },
        "owner_id": {
            "type": "string",
            "format": "uuid",
            "title": "Owner Id"
        },
        "candidate_scope_rules": {
            "items": {
                "$ref": "#/components/schemas/StylistScopeRule"
            },
            "type": "array",
            "title": "Candidate Scope Rules",
            "default": []
        },
        "underpinnings_query_template": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Underpinnings Query Template"
        },
        "organization_id": {
            "anyOf": [
                {
                    "type": "string",
                    "format": "uuid"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Organization Id"
        }
    },
    "type": "object",
    "required": [
        "id",
        "created_at",
        "updated_at",
        "name",
        "styling_template_values",
        "public",
        "owner_id"
    ],
    "title": "StylistPublic",
    "description": "Schema for stylist public response."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string",
            "input": null,
            "ctx": {}
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

PUT /api/v1/stylists/{id}

Update Stylist

Description

Update a stylist.

Admins can update any stylist and transfer ownership via owner_id. Non-admins can only update their own stylists and cannot change owner_id.

Organization transfer: - To transfer a personal stylist to an organization: set organization_id to the target org ID - To transfer a stylist out of an organization: set organization_id to None (org owner only)

Input parameters

Parameter In Type Default Nullable Description
OAuth2PasswordBearer header string N/A No
id path string No
organization_id query No

Request body

{
    "name": "string",
    "styling_template_values": {
        "AESTHETIC": "preppy-collegiate",
        "COLOR_RULES": "BLACKBEAN/BLACK → black\nNAVY/DARKBLUE → navy...",
        "FILLER_SPECIFIC_NOTES": "Real sneakers exist in catalog, use these first...",
        "LAYERING_RULES": "Max 3-4 colors per look. Preppy combos encouraged...",
        "OPTIONALITY_RULES": "Upper_layer optional if mid_layer provides enough visual interest...",
        "SELECTION_LOGIC": "The core product MUST ALWAYS appear in the items array...",
        "STYLING_DNA": "Silhouette: preppy-collegiate. Layering is key..."
    },
    "public": true,
    "owner_id": "8796e683-7ab4-413c-9a3d-214ed94be136",
    "candidate_scope_rules": [
        "brand"
    ],
    "underpinnings_query_template": null,
    "organization_id": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "properties": {
        "name": {
            "type": "string",
            "maxLength": 255,
            "title": "Name",
            "description": "Name of the stylist"
        },
        "styling_template_values": {
            "$ref": "#/components/schemas/StylistTemplateValuesSchema",
            "title": "Styling Template Values",
            "description": "Template values for AI prompt composition"
        },
        "public": {
            "type": "boolean",
            "title": "Public",
            "description": "Whether the stylist is publicly accessible"
        },
        "owner_id": {
            "type": "string",
            "format": "uuid",
            "title": "Owner Id",
            "description": "Transfer ownership to another user. Only admins can set this."
        },
        "candidate_scope_rules": {
            "items": {
                "$ref": "#/components/schemas/StylistScopeRule"
            },
            "type": "array",
            "title": "Candidate Scope Rules",
            "description": "Which predicates narrow the candidate pool, compared against the product being shot. Each is NULL-permissive: an unclassified product stays eligible. Gender, age band and slot compatibility always apply and are not listed here."
        },
        "underpinnings_query_template": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Underpinnings Query Template",
            "description": "Custom WHERE clause for product filtering. Admin-only. \nAvailable wildcards (use :wildcard syntax for SQLAlchemy bound parameters):\n- :core_id (UUID) - Core product ID\n- :core_brand (string) - Core product brand\n- :core_brand_collection (string) - Core product brand collection\n- :core_gender (string) - Core product gender (MALE/FEMALE/UNISEX)\n- :core_season (string) - Core product season\n- :core_year (int) - Core product year\n- :core_in_store_date (datetime) - Core product in-store date\n- :core_product_family (string) - Core product family (APPAREL/FOOTWEAR/ACCESSORIES/BEAUTY)\n- :core_product_type (string) - Core product type\n- :core_age_class (string) - Core product age class\n- :core_owner_id (UUID) - Core product owner ID\n- :core_organization_id (UUID) - Core product organization ID\n- :core_theme (string) - Core product theme\n- :subject_gender (string) - Subject's gender (MALE/FEMALE/OTHER)\n\nSupported expression grammar: AND/OR/NOT, parentheses, =/!=/<>/</<=/>/>=,\nIS NULL/IS NOT NULL, IN/NOT IN, LIKE/ILIKE, literals, and the lower(), upper(),\ntrim(), and coalesce() functions. Allowed fields are id, brand, brand_collection,\ngender, season, year, in_store_date, age_class, master_item_code, color_name,\nowner_id, organization_id, theme, product_type, and product_family (optionally\nqualified by product/p, ptr, or pf as shown below). Statements, subqueries,\ncomments, and unknown fields/functions/parameters are rejected.\n\nExample: \"lower(trim(product.brand)) = lower(trim(:core_brand)) AND product.season = :core_season\"\n(normalize brand with lower(trim(...)) on both sides so stored whitespace/casing still matches)\n"
        },
        "organization_id": {
            "anyOf": [
                {
                    "type": "string",
                    "format": "uuid"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Organization Id",
            "description": "Organization to transfer this stylist to"
        }
    },
    "type": "object",
    "title": "StylistUpdate",
    "description": "Schema for updating an existing stylist."
}

Responses

{
    "id": "14598d93-818e-42bc-8247-7105877bd4ee",
    "created_at": "2022-04-13T15:42:05.901Z",
    "updated_at": "2022-04-13T15:42:05.901Z",
    "name": "string",
    "styling_template_values": {
        "AESTHETIC": "preppy-collegiate",
        "COLOR_RULES": "BLACKBEAN/BLACK → black\nNAVY/DARKBLUE → navy...",
        "FILLER_SPECIFIC_NOTES": "Real sneakers exist in catalog, use these first...",
        "LAYERING_RULES": "Max 3-4 colors per look. Preppy combos encouraged...",
        "OPTIONALITY_RULES": "Upper_layer optional if mid_layer provides enough visual interest...",
        "SELECTION_LOGIC": "The core product MUST ALWAYS appear in the items array...",
        "STYLING_DNA": "Silhouette: preppy-collegiate. Layering is key..."
    },
    "public": true,
    "owner_id": "dbe6d410-f13d-4b3a-8ea5-b9be2b0c77d0",
    "candidate_scope_rules": [
        "brand"
    ],
    "underpinnings_query_template": null,
    "organization_id": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id"
        },
        "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
        },
        "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At"
        },
        "name": {
            "type": "string",
            "title": "Name"
        },
        "styling_template_values": {
            "$ref": "#/components/schemas/StylistTemplateValuesSchema"
        },
        "public": {
            "type": "boolean",
            "title": "Public"
        },
        "owner_id": {
            "type": "string",
            "format": "uuid",
            "title": "Owner Id"
        },
        "candidate_scope_rules": {
            "items": {
                "$ref": "#/components/schemas/StylistScopeRule"
            },
            "type": "array",
            "title": "Candidate Scope Rules",
            "default": []
        },
        "underpinnings_query_template": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Underpinnings Query Template"
        },
        "organization_id": {
            "anyOf": [
                {
                    "type": "string",
                    "format": "uuid"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Organization Id"
        }
    },
    "type": "object",
    "required": [
        "id",
        "created_at",
        "updated_at",
        "name",
        "styling_template_values",
        "public",
        "owner_id"
    ],
    "title": "StylistPublic",
    "description": "Schema for stylist public response."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string",
            "input": null,
            "ctx": {}
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

DELETE /api/v1/stylists/{id}

Delete Stylist

Description

Delete a stylist.

Input parameters

Parameter In Type Default Nullable Description
OAuth2PasswordBearer header string N/A No
id path string No
organization_id query No

Responses

{
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "message": {
            "type": "string",
            "title": "Message"
        }
    },
    "type": "object",
    "required": [
        "message"
    ],
    "title": "Message"
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string",
            "input": null,
            "ctx": {}
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

POST /api/v1/stylists/agent-create

Agent Create Stylist

Description

Stylist for the job's organization (plan 002). JOB-SCOPED token only.

Content-aware get-or-create on the (organization, name) FAMILY: a row of the same brand line whose values already match is returned UNTOUCHED (created: false); diverging values create a new versioned sibling (<name> (n)) instead of overwriting — the attach then points the guideline at it, last-extraction-wins. Values are never written onto an existing row: it cannot say whether they are an operator's refinement or a stale run's output, so the new reading arrives as a new row and the old one stays in the palette.

The body carries the name and a source-backed subset of the seven values and nothing else. The backend resolves the omitted values from the shooting's current stylist or the seeded default. Organization, owner and public come from the job; underpinnings_query_template is not settable here AT ALL and stays null — it is raw SQL interpolated into the product query rather than bound, which is why it is superuser-only, and text an agent synthesized from scraped pages is exactly what must never reach it. Scoping the product pool is an operator's job afterwards, in the admin editor.

The response is narrow BY DESIGN (StylistAgentPublic): returning StylistPublic would echo an absorbed stylist's seven values and its SQL template back to a token that guessed a name, which is the read this token is deliberately not granted.

409 when the job has no target shooting — an org-level stylist that no guideline will ever point at is permanent litter.

Input parameters

Parameter In Type Default Nullable Description
OAuth2PasswordBearer header string N/A No

Request body

{
    "name": "string",
    "styling_template_values": {
        "AESTHETIC": null,
        "STYLING_DNA": null,
        "LAYERING_RULES": null,
        "COLOR_RULES": null,
        "SELECTION_LOGIC": null,
        "OPTIONALITY_RULES": null,
        "FILLER_SPECIFIC_NOTES": null
    }
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "properties": {
        "name": {
            "type": "string",
            "maxLength": 255,
            "title": "Name",
            "description": "Name of the stylist"
        },
        "styling_template_values": {
            "$ref": "#/components/schemas/StylistAgentTemplateValuesSchema",
            "description": "Source-backed template values to merge into the target guidelines stylist"
        }
    },
    "additionalProperties": false,
    "type": "object",
    "required": [
        "name",
        "styling_template_values"
    ],
    "title": "StylistAgentCreate",
    "description": "Body of ``POST /stylists/agent-create`` (plan 002). JOB-SCOPED tokens.\n\nTwo fields, and no way to widen them: organization, owner, ``public`` and\n``underpinnings_query_template`` are all derived from the job. The values\nmay be a source-backed subset; the backend merges them over the stylist\nalready selected by the target guidelines before persisting a complete\nseven-field version. The SQL template in particular is superuser-only for\na reason — it is interpolated into a query string rather than bound, so a\nclause authored from extracted text could escape the ownership filter.\n\n``extra=\"forbid\"`` rather than the pydantic default: a body carrying\n``public: true`` must fail loudly instead of being accepted and silently\nstripped, which is indistinguishable from being honoured.\n\nThe delta validators live on ``StylistAgentTemplateValuesSchema``, not on\n``StylistTemplateValuesSchema``, which operator create/update also share."
}

Responses

{
    "id": "3dbc3f05-df8b-47eb-af32-0e35c798c418",
    "name": "string",
    "created": true
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id"
        },
        "name": {
            "type": "string",
            "title": "Name"
        },
        "created": {
            "type": "boolean",
            "title": "Created"
        }
    },
    "type": "object",
    "required": [
        "id",
        "name",
        "created"
    ],
    "title": "StylistAgentPublic",
    "description": "Response of ``POST /stylists/agent-create``. Deliberately NOT ``StylistPublic``.\n\nThat schema carries ``styling_template_values`` and\n``underpinnings_query_template``, so returning it would echo an existing\nstylist's values — and any SQL a superuser wrote on it — back to a token\nthat named the stylist by guessing its label. The job token is granted no\nread of ``/stylists``; a write that returns the whole row would be that\nread with extra steps.\n\n``created`` is false when an existing ``(organization, name)`` was absorbed."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string",
            "input": null,
            "ctx": {}
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

Schemas

HTTPValidationError

Name Type Description
detail Array<ValidationError>

Message

Name Type Description
message string

StylistAgentCreate

Name Type Description
name string Name of the stylist
styling_template_values StylistAgentTemplateValuesSchema Source-backed template values to merge into the target guidelines stylist

StylistAgentPublic

Name Type Description
created boolean
id string(uuid)
name string

StylistAgentTemplateValuesSchema

Name Type Description
AESTHETIC
COLOR_RULES
FILLER_SPECIFIC_NOTES
LAYERING_RULES
OPTIONALITY_RULES
SELECTION_LOGIC
STYLING_DNA

StylistCreate

Name Type Description
candidate_scope_rules Array<StylistScopeRule> Which predicates narrow the candidate pool, compared against the product being shot. Each is NULL-permissive: an unclassified product stays eligible. Gender, age band and slot compatibility always apply and are not listed here.
name string Name of the stylist
organization_id Organization this stylist belongs to
owner_id Owner user ID. Only admins can set this. If not provided, defaults to current user.
public boolean Whether the stylist is publicly accessible
styling_template_values StylistTemplateValuesSchema Template values for AI prompt composition
underpinnings_query_template Custom WHERE clause for product filtering. Admin-only. Available wildcards (use :wildcard syntax for SQLAlchemy bound parameters): - :core_id (UUID) - Core product ID - :core_brand (string) - Core product brand - :core_brand_collection (string) - Core product brand collection - :core_gender (string) - Core product gender (MALE/FEMALE/UNISEX) - :core_season (string) - Core product season - :core_year (int) - Core product year - :core_in_store_date (datetime) - Core product in-store date - :core_product_family (string) - Core product family (APPAREL/FOOTWEAR/ACCESSORIES/BEAUTY) - :core_product_type (string) - Core product type - :core_age_class (string) - Core product age class - :core_owner_id (UUID) - Core product owner ID - :core_organization_id (UUID) - Core product organization ID - :core_theme (string) - Core product theme - :subject_gender (string) - Subject's gender (MALE/FEMALE/OTHER) Supported expression grammar: AND/OR/NOT, parentheses, =/!=/<>//>=, IS NULL/IS NOT NULL, IN/NOT IN, LIKE/ILIKE, literals, and the lower(), upper(), trim(), and coalesce() functions. Allowed fields are id, brand, brand_collection, gender, season, year, in_store_date, age_class, master_item_code, color_name, owner_id, organization_id, theme, product_type, and product_family (optionally qualified by product/p, ptr, or pf as shown below). Statements, subqueries, comments, and unknown fields/functions/parameters are rejected. Example: "lower(trim(product.brand)) = lower(trim(:core_brand)) AND product.season = :core_season" (normalize brand with lower(trim(...)) on both sides so stored whitespace/casing still matches)

StylistPublic

Name Type Description
candidate_scope_rules Array<StylistScopeRule>
created_at string(date-time)
id string(uuid)
name string
organization_id
owner_id string(uuid)
public boolean
styling_template_values StylistTemplateValuesSchema
underpinnings_query_template
updated_at string(date-time)

StylistScopeRule

Type: string

StylistsPublic

Name Type Description
count integer
created_at string(date-time)
data Array<StylistPublic>
id string(uuid)
updated_at string(date-time)

StylistTemplateValuesSchema

Name Type Description
AESTHETIC string Style aesthetic (e.g., 'preppy-collegiate', 'minimalist', 'streetwear')
COLOR_RULES string Color name mappings (e.g., 'BLACKBEAN/BLACK → black')
FILLER_SPECIFIC_NOTES string Guidance on when to use filler products vs catalog items
LAYERING_RULES string Color limits, print mixing rules, bottoms variety guidelines
OPTIONALITY_RULES string Rules for what's optional in a look (layers, accessories)
SELECTION_LOGIC string Product pairing rules, role assignments, track set matching rules
STYLING_DNA string Core styling rules: silhouettes, layering philosophy, attitude, footwear preferences

StylistUpdate

Name Type Description
candidate_scope_rules Array<StylistScopeRule> Which predicates narrow the candidate pool, compared against the product being shot. Each is NULL-permissive: an unclassified product stays eligible. Gender, age band and slot compatibility always apply and are not listed here.
name string Name of the stylist
organization_id Organization to transfer this stylist to
owner_id string(uuid) Transfer ownership to another user. Only admins can set this.
public boolean Whether the stylist is publicly accessible
styling_template_values StylistTemplateValuesSchema Template values for AI prompt composition
underpinnings_query_template Custom WHERE clause for product filtering. Admin-only. Available wildcards (use :wildcard syntax for SQLAlchemy bound parameters): - :core_id (UUID) - Core product ID - :core_brand (string) - Core product brand - :core_brand_collection (string) - Core product brand collection - :core_gender (string) - Core product gender (MALE/FEMALE/UNISEX) - :core_season (string) - Core product season - :core_year (int) - Core product year - :core_in_store_date (datetime) - Core product in-store date - :core_product_family (string) - Core product family (APPAREL/FOOTWEAR/ACCESSORIES/BEAUTY) - :core_product_type (string) - Core product type - :core_age_class (string) - Core product age class - :core_owner_id (UUID) - Core product owner ID - :core_organization_id (UUID) - Core product organization ID - :core_theme (string) - Core product theme - :subject_gender (string) - Subject's gender (MALE/FEMALE/OTHER) Supported expression grammar: AND/OR/NOT, parentheses, =/!=/<>//>=, IS NULL/IS NOT NULL, IN/NOT IN, LIKE/ILIKE, literals, and the lower(), upper(), trim(), and coalesce() functions. Allowed fields are id, brand, brand_collection, gender, season, year, in_store_date, age_class, master_item_code, color_name, owner_id, organization_id, theme, product_type, and product_family (optionally qualified by product/p, ptr, or pf as shown below). Statements, subqueries, comments, and unknown fields/functions/parameters are rejected. Example: "lower(trim(product.brand)) = lower(trim(:core_brand)) AND product.season = :core_season" (normalize brand with lower(trim(...)) on both sides so stored whitespace/casing still matches)

ValidationError

Name Type Description
ctx
input
loc Array<>
msg string
type string

Security schemes

Name Type Scheme Description
OAuth2PasswordBearer oauth2