True Fit Closet API

Information about the profile's closet.

OpenAPI Specification

true-fit-closet-api-openapi.yml Raw ↑
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