OpenAPI Specification
openapi: 3.2.0
info:
title: True Fit Closet API
version: '1.0'
description: 'Operations tagged Closet across 2 of this provider''s published API definitions: true-fit-consumer-api-openapi.json, true-fit-partner-api-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: /profile/public/v3/{tla}
- url: https://partner.truefitcorp.com/api
description: Partner API
tags:
- name: Closet
description: Information about the profile's closet.
paths:
/profiles/{profileId}/closet:
servers:
- url: /profile/public/v3/{tla}
get:
tags:
- Closet
summary: Retrieve the closet items for the given profile.
parameters:
- name: X-TF-UserToken
in: header
description: The session token for the current user.
required: true
style: simple
explode: false
schema:
type: string
- name: profileId
in: path
required: true
style: simple
explode: false
schema:
type: string
- name: category
in: query
required: false
style: form
explode: true
schema:
type: string
enum:
- Bottoms
- Tops
- Dresses
- Shoes
- Bras
responses:
'200':
description: The closet items for the given profile, filtered by category if specified.
headers:
X-TF-UserToken:
description: The updated token for the user. This updated token should be used on all following requests. This header is only present when the token has cycled.
style: simple
explode: false
schema:
type: string
X-TF-UserTokenMaxAge:
description: This will be most useful when storing the token as a cookie. The value is the suggested max age of the token (in seconds).
style: simple
explode: false
schema:
type: integer
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ClosetItem'
post:
tags:
- Closet
summary: Saves a closet item for the given profile.
parameters:
- name: X-TF-UserToken
in: header
description: The session token for the current user.
required: true
style: simple
explode: false
schema:
type: string
- name: profileId
in: path
required: true
style: simple
explode: false
schema:
type: string
requestBody:
$ref: '#/components/requestBodies/ClosetItem'
responses:
'200':
description: 'The closet item that was successfully created.
The classification is either a value returned from the /brands/{brandId}/classes endpoint or one of the following - ''NotSure'' or ''NoneOfThese''
The brand style id is either the id of a brand style returned from the /brands/{brandId}/styles endpoint or one of the following - ''NotSure'' or ''NoneOfThese''
The style attributes is a map that is composed of a styleType key and an associated value in the values list returned from the `/style-attributes` endpoint for the styleType and one of the following - `NotSure` or `NoneOfThese`
'
headers:
X-TF-UserToken:
description: The updated token for the user. This updated token should be used on all following requests. This header is only present when the token has cycled.
style: simple
explode: false
schema:
type: string
X-TF-UserTokenMaxAge:
description: This will be most useful when storing the token as a cookie. The value is the suggested max age of the token (in seconds).
style: simple
explode: false
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ClosetItem'
/profiles/{profileId}/closet/{closetId}:
servers:
- url: /profile/public/v3/{tla}
get:
tags:
- Closet
summary: Get a specific closet item by ID.
parameters:
- name: X-TF-UserToken
in: header
description: The session token for the current user.
required: true
style: simple
explode: false
schema:
type: string
- name: profileId
in: path
required: true
style: simple
explode: false
schema:
type: string
- name: closetId
in: path
required: true
style: simple
explode: false
schema:
type: string
responses:
'200':
description: The closet item with that ID.
headers:
X-TF-UserToken:
description: The updated token for the user. This updated token should be used on all following requests. This header is only present when the token has cycled.
style: simple
explode: false
schema:
type: string
X-TF-UserTokenMaxAge:
description: This will be most useful when storing the token as a cookie. The value is the suggested max age of the token (in seconds).
style: simple
explode: false
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ClosetItem'
put:
tags:
- Closet
summary: Updates a closet item for the given profile.
description: The closetId in the path must match the id in the body.
parameters:
- name: X-TF-UserToken
in: header
description: The session token for the current user.
required: true
style: simple
explode: false
schema:
type: string
- name: profileId
in: path
required: true
style: simple
explode: false
schema:
type: string
- name: closetId
in: path
required: true
style: simple
explode: false
schema:
type: string
- name: stillFits
in: query
description: 'Passed as true if an expired closet item still fits the child profile.
'
required: false
style: form
explode: true
schema:
type: boolean
enum:
- true
requestBody:
$ref: '#/components/requestBodies/ClosetItem'
responses:
'200':
description: 'The closet item that was successfully created.
'
headers:
X-TF-UserToken:
description: The updated token for the user. This updated token should be used on all following requests. This header is only present when the token has cycled.
style: simple
explode: false
schema:
type: string
X-TF-UserTokenMaxAge:
description: This will be most useful when storing the token as a cookie. The value is the suggested max age of the token (in seconds).
style: simple
explode: false
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ClosetItem'
delete:
tags:
- Closet
summary: Deletes a Closet Item
parameters:
- name: X-TF-UserToken
in: header
description: The session token for the current user.
required: true
style: simple
explode: false
schema:
type: string
- name: profileId
in: path
required: true
style: simple
explode: false
schema:
type: string
- name: closetId
in: path
required: true
style: simple
explode: false
schema:
type: string
- name: stillFits
in: query
description: 'Passed as false if the expired closet item no longer fits for the child profile.
'
required: false
style: form
explode: true
schema:
type: boolean
enum:
- false
responses:
'200':
description: The closet item that was successfully deleted.
headers:
X-TF-UserToken:
description: The updated token for the user. This updated token should be used on all following requests. This header is only present when the token has cycled.
style: simple
explode: false
schema:
type: string
X-TF-UserTokenMaxAge:
description: This will be most useful when storing the token as a cookie. The value is the suggested max age of the token (in seconds).
style: simple
explode: false
schema:
type: integer
/partner/{partnerId}/profile/{profileId}/closet:
parameters:
- $ref: '#/components/parameters/partnerId'
- $ref: '#/components/parameters/profileId'
- $ref: '#/components/parameters/partnerUserId'
- $ref: '#/components/parameters/tfPartnerUserId'
servers:
- url: https://partner.truefitcorp.com/api
description: Partner API
get:
operationId: listClosetItems
tags:
- Closet
summary: List the profile's closet items
responses:
'200':
description: 'The profile''s closet items. String fields are returned lowercased - `sellingSize`
is the exception and is stored and returned verbatim.
'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ClosetItem_2'
examples:
single:
value:
- closetId: '1893471'
department: womens
category: bottoms
hierarchyLabels:
- womens
- bottoms
brand: nike
sellingLocale: us
sellingSize: L
sizeVariants:
sizeType: regular
fitAttributes: null
updatedAt: '2026-07-31T16:02:10.000Z'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/ProfileNotFound'
security:
- partnerApiKey: []
post:
operationId: createClosetItem
tags:
- Closet
summary: Add a closet item
description: 'Adds a garment the user owns. The submitted combination of `brand`, `department`,
`category`, `sellingLocale`, `hierarchyLabels`, `sellingSize`, and
`sizeVariants.sizeType` must resolve to a size that exists in True Fit''s catalogue -
arbitrary garments cannot be added. See the integration guide for how to pick values
that validate.
Adding a closet item re-runs body estimation, so a recommendation requested
immediately afterwards may return `userEstimationInProgress`.
'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateClosetItemRequest'
examples:
womensBottoms:
value:
department: womens
category: bottoms
hierarchyLabels:
- womens
- bottoms
brand: Nike
sellingLocale: US
sellingSize: L
sizeVariants:
sizeType: regular
responses:
'201':
description: Closet item added. No response body.
'400':
$ref: '#/components/responses/ValidationFailed'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/ProfileNotFound'
'500':
$ref: '#/components/responses/UnvalidatedClosetSize'
security:
- partnerApiKey: []
/partner/{partnerId}/profile/{profileId}/closet/{closetItemId}:
parameters:
- $ref: '#/components/parameters/partnerId'
- $ref: '#/components/parameters/profileId'
- $ref: '#/components/parameters/closetItemId'
- $ref: '#/components/parameters/partnerUserId'
- $ref: '#/components/parameters/tfPartnerUserId'
servers:
- url: https://partner.truefitcorp.com/api
description: Partner API
put:
operationId: updateClosetItem
tags:
- Closet
summary: Update a closet item
description: 'Partially updates a closet item. The fields you send are merged over the stored item and
the merged result is re-validated against True Fit''s size catalogue, so a partial update
can be rejected because of fields you did not send.
'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateClosetItemRequest'
examples:
resize:
value:
sellingSize: M
responses:
'200':
description: Closet item updated. No response body.
'400':
$ref: '#/components/responses/ValidationFailed'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/ProfileNotFound'
'500':
$ref: '#/components/responses/UnvalidatedClosetSize'
security:
- partnerApiKey: []
delete:
operationId: deleteClosetItem
tags:
- Closet
summary: Delete a closet item
responses:
'204':
description: Deleted. No response body.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/ProfileNotFound'
security:
- partnerApiKey: []
components:
parameters:
closetItemId:
name: closetItemId
in: path
required: true
description: A closet item identifier, from the `closetId` field of `GET /closet`.
schema:
type: string
example: '1893471'
partnerUserId:
name: partnerUserId
in: query
required: false
description: 'Your own identifier for the user, as passed to `GET /id-sync`. Send either this or
`tfPartnerUserId`; omitting both returns `400`. If both are sent, `tfPartnerUserId` wins.
'
schema:
type: string
example: acme-user-42817
partnerId:
name: partnerId
in: path
required: true
description: Your partner identifier, issued during onboarding.
schema:
type: string
example: acme
profileId:
name: profileId
in: path
required: true
description: 'A profile belonging to the identified user, from `GET /profile`. Profiles belonging to
another user return `404` rather than `403`, so the endpoint cannot be used to probe
for the existence of other users'' profiles.
'
schema:
type: string
format: uuid
example: 7c9e6679-7425-40de-944b-e07fc1f90ae7
tfPartnerUserId:
name: tfPartnerUserId
in: query
required: false
description: 'True Fit''s identifier for the user, returned by `GET /id-sync`. Send either this or
`partnerUserId`; omitting both returns `400`. Takes precedence when both are sent.
'
schema:
type: string
example: p-3f9c1a80-5d2e-4a17-9b64-8e0c2d7f1a55
responses:
Unauthorized:
description: 'Missing or invalid Basic credentials, or a user identifier that does not match a known
partner user.
'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
missingCredentials:
value:
statusCode: 401
message: Missing Basic auth credentials
error: Unauthorized
invalidCredentials:
value:
statusCode: 401
message: Invalid credentials
error: Unauthorized
unknownUser:
summary: The identifier has no True Fit mapping - call GET /id-sync first
value:
statusCode: 401
message: Unknown partner user
error: Unauthorized
ProfileNotFound:
description: 'The `profileId` does not exist or does not belong to the identified user. Also returned
when the `partnerId` is unknown or disabled.
'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
profileNotFound:
value:
statusCode: 404
message: Profile not found
error: Not Found
ValidationFailed:
description: 'The request body or query string failed schema validation. `error` maps each failing
field path to its message; array indices appear as the first path segment.
'
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
examples:
missingField:
value:
message: Validation failed
error:
0.retailerDomain: 'Invalid input: expected string, received undefined'
badEnum:
value:
message: Validation failed
error:
category: 'Invalid option: expected one of "belts"|"bottoms"|"bras"'
UnvalidatedClosetSize:
description: 'A server error. On these endpoints it also indicates a closet item that does not match a
size in True Fit''s catalogue, in which case retrying the identical payload will not
succeed. Verify the `brand`, `department`, `category`, `sellingLocale`, `hierarchyLabels`,
`sellingSize`, and `sizeVariants.sizeType` combination; `sellingSize: null` is not
accepted.
'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalidSize:
value:
statusCode: 500
message: Internal server error
schemas:
ClosetItem_2:
allOf:
- $ref: '#/components/schemas/CreateClosetItemRequest'
- type: object
required:
- closetId
- updatedAt
properties:
closetId:
type: string
description: Identifier for this closet item, used in the item's path.
example: '1893471'
updatedAt:
type: string
format: date-time
WomensSleeveLength:
type: string
enum:
- LongSleeve
- ShortSleeve
- Strapless
- Tank
- ThreeQuarterSleeve
WomensBottomsStyle:
type: string
enum:
- Boot
- Boyfriend
- Capri
- Flare
- Legging
- Skinny
- Straight
- Trouser
- Wide
Error:
type: object
description: Standard error body.
required:
- statusCode
- message
properties:
statusCode:
type: integer
example: 404
message:
type: string
example: Profile not found
error:
type: string
example: Not Found
WomensBraBandFit:
type: string
enum:
- DigsIn
- JustRight
- RidesUp
WomensRise:
type: string
enum:
- Low
- Mid
- High
- Ultra
WomensTopsStyle:
type: string
enum:
- Blouse
- Polo
- Sweater
- TailoredShirt
- Tank
- Tee
- Tunic
ClosetCategory:
type: string
description: 'Garment category. Matched case-insensitively and stored lowercased.
'
enum:
- belts
- bottoms
- bras
- dresses
- hats
- hosiery
- intimates
- gloves
- neckwear
- nightgowns
- not apparel
- other
- pajamabottoms
- pajamatops
- pajamasets
- robes
- shoes
- scarves
- socks
- suits
- swim
- swimbottoms
- swimsuits
- swimtops
- tops
example: bottoms
MensBottomsStyle:
type: string
enum:
- Boot
- Skinny
- Straight
- Wide
FitDescription:
type: string
enum:
- ABitSmall
- JustRight
- ABitLarge
Department:
type: string
description: 'Garment department. Matched case-insensitively - `Womens` and `womens` are both accepted
- and stored lowercased.
'
enum:
- baby
- boys
- donotrecommend
- girls
- maternity
- mens
- not apparel
- other
- unisexkids
- womens
- unisex
example: womens
MensPantsFit:
type: string
enum:
- FormFitting
- SemiFitted
- Relaxed
ClosetItem:
required:
- ageGroup
- brandId
- category
- gender
type: object
properties:
id:
type: string
description: This field is populated by the server, never created by the client.
readOnly: true
example: someClosetId
brandId:
type: string
description: "The brandId corresponding to the `id` field on the brands returned by the /brands endpoint. It is valid to be empty ONLY when dealing with a profile with an ageGroup of `Child` \n"
category:
$ref: '#/components/schemas/Category'
gender:
$ref: '#/components/schemas/Gender'
ageGroup:
$ref: '#/components/schemas/AgeGroup'
classification:
type: string
description: 'The classification is either a value returned from the `/brands/{brandId}/classes` endpoint or one of the following - `NotSure` or `NoneOfThese`
'
sizeId:
type: string
brandStyleId:
type: string
description: 'The brand style id is either the id of a brand style returned from the `/brands/{brandId}/styles` endpoint or one of the following - `NotSure` or `NoneOfThese`
'
styles:
$ref: '#/components/schemas/StyleAttributes'
isExpired:
type: boolean
description: 'Expiration status of the closet item. This field is populated by the server, never created by the client.
'
readOnly: true
WomensSilhouette:
type: string
enum:
- ALine
- Empire
- Maxi
- Sheath
- Shift
- Wrap
WomensBraCupFit:
type: string
enum:
- Gaps
- JustRight
- Overflows
SizeType:
type: string
description: 'Size range the garment belongs to. Matched case-insensitively and stored lowercased.
'
enum:
- regular
- plus
- juniors
- petite
- slim
- bigandtall
- curvy
- unisex
- tall
- husky
example: regular
ValidationError:
type: object
description: Schema validation failure. Note this body carries no `statusCode`.
required:
- message
- error
properties:
message:
type: string
example: Validation failed
error:
type: object
description: Failing field path to error message.
additionalProperties:
type: string
CreateClosetItemRequest:
type: object
description: 'A garment the user owns. The combination of fields must resolve to a size in True Fit''s
catalogue or the request is rejected - see the integration guide.
'
required:
- department
- category
- hierarchyLabels
- brand
- sellingLocale
- sellingSize
- sizeVariants
properties:
department:
$ref: '#/components/schemas/Department'
category:
$ref: '#/components/schemas/ClosetCategory'
hierarchyLabels:
type: array
description: 'The garment''s position in the brand''s category hierarchy, coarsest first. Must match
the hierarchy True Fit holds for that brand, department, and category. Stored
lowercased.
'
items:
type: string
example:
- womens
- bottoms
brand:
type: string
description: Brand name. Stored lowercased.
example: Nike
sellingLocale:
type: string
minLength: 2
maxLength: 2
description: 'Two-letter country code for the market the garment was bought in. Stored lowercased.
'
example: US
sellingSize:
type:
- string
- 'null'
minLength: 1
description: 'The size on the garment''s label, exactly as printed. Stored and returned verbatim,
not lowercased. Always send a real size - `null` is not accepted.
'
example: L
sizeVariants:
type: object
required:
- sizeType
properties:
sizeType:
$ref: '#/components/schemas/SizeType'
sleeveLength:
type: string
shoeWidth:
type: string
cupSize:
type: string
fitAttributes:
type:
- object
- 'null'
description: 'Free-form fit notes about this garment as string key/value pairs. Defaults to `null`.
'
additionalProperties:
type: string
UpdateClosetItemRequest:
type: object
description: 'Every field is optional. The fields you send are merged over the stored item and the
merged result is re-validated against True Fit''s catalogue.
'
properties:
department:
$ref: '#/components/schemas/Department'
category:
$ref: '#/components/schemas/ClosetCategory'
hierarchyLabels:
type: array
items:
type: string
brand:
type: string
sellingLocale:
type: string
minLength: 2
maxLength: 2
sellingSize:
type:
- string
- 'null'
minLength: 1
sizeVariants:
type: object
required:
- sizeType
properties:
sizeType:
$ref: '#/components/schemas/SizeType'
sleeveLength:
type: string
shoeWidth:
type: string
cupSize:
type: string
fitAttributes:
type:
- object
- 'null'
additionalProperties:
type: string
StyleAttributes:
type: object
properties:
WomensBraBandFit:
$ref: '#/components/schemas/WomensBraBandFit'
WomensBraCupFit:
$ref: '#/components/schemas/WomensBraCupFit'
WomensBraStyle:
$ref: '#/components/schemas/WomensBraStyle'
WomensSilhouette:
$ref: '#/components/schemas/WomensSilhouette'
WomensTopsStyle:
$ref: '#/components/schemas/WomensTopsStyle'
WomensSleeveLength:
$ref: '#/components/schemas/WomensSleeveLength'
WomensBottomsStyle:
$ref: '#/components/schemas/WomensBottomsStyle'
WomensRise:
$ref: '#/components/schemas/WomensRise'
MensPantsFit:
$ref: '#/components/schemas/MensPantsFit'
MensBottomsStyle:
$ref: '#/components/schemas/MensBottomsStyle'
ClosetItemAge:
$ref: '#/components/schemas/ClosetItemAge'
FitDescription:
$ref: '#/components/schemas/FitDescription'
description: 'The styles is a map that is composed of a styleType key and an associated value in the values list returned from the `/style-attributes` endpoint for the styleType and one of the following - `NotSure` or `NoneOfThese`
'
example:
WomensSleeveLength: NotSure
WomensSilhouette: ALine
ClosetItemAge:
type: string
enum:
- LessThanOneYear
- OneYearOrOlder
Gender:
type: string
example: Female
enum:
- Female
- Male
- Unisex
AgeGroup:
type: string
example: Adult
enum:
- Adult
- Child
WomensBraStyle:
type: string
enum:
- LowCoverage
- MediumCoverage
- FullCoverage
Category:
type: string
example: Bottoms
enum:
- Bottoms
- Dresses
- Shoes
- Tops
- Bras
requestBodies:
ClosetItem:
description: ClosetItem object that represents an article of clothing the person being shopped for already wears and likes how it fits.
content:
application/json:
schema:
$ref: '#/components/schemas/ClosetItem'
required: true
securitySchemes:
partnerApiKey:
type: http
scheme: basic
description: 'Empty username, partner API key as the password:
`Authorization: Basic <base64(":" + apiKey)>`.
'
x-refined-from:
- true-fit-consumer-api-openapi.json
- true-fit-partner-api-openapi.json
x-explorer-enabled: false