{
 "openapi": "3.1.0",
 "info": {
  "title": "Flume Partner API",
  "description": "Find tile and vinyl flooring by photo, price it for a quantity and a US ZIP code, and hand the\nuser over to Flume signed in. Server to server: every call carries your partner key as\n`X-Flume-Partner-Key`, and every call made for a user also carries that user's access token as\n`X-Flume-User-Token`.\n\n**How it fits together**\n\n1. `POST /users/trigger-verification`: verify a user, send the code.\n2. `POST /users/confirm-verification`: verify a user, confirm the code. It returns their access token.\n3. `POST /search`: search by photo. `GET /filters` lists the filter options.\n4. `GET /products/{sku_uuid}`: one product's photos, price, specification and shipping.\n5. `POST /request-instant-quote`: the delivered price for a quantity and a ZIP code.\n   `GET /quotes/{quote_uuid}` reads a quote that is still pricing.\n6. `POST /deep-links`: a one-time link into the user's Flume account.\n\nSteps 3 to 6 need both headers. Prices are US dollars, sent as text with 2 decimals (`\"6.40\"`).\nGuides and the error catalog: https://docs.tryflume.ai\n",
  "version": "2.0.0"
 },
 "servers": [
  {
   "url": "https://sandbox-api.tryflume.ai/partner/v1",
   "description": "Sandbox"
  },
  {
   "url": "https://ssapi.tryflume.ai/partner/v1",
   "description": "Live (early access, by request; not yet open to new partners)"
  }
 ],
 "paths": {
  "/users/trigger-verification": {
   "post": {
    "tags": [
     "Users"
    ],
    "operationId": "triggerVerification",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TriggerVerificationRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/VerificationSent"
        }
       }
      },
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "PARTNER_KEY_INVALID",
          "message": "The API key is missing, invalid, revoked or expired.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The partner key is missing, unknown, revoked or expired (`PARTNER_KEY_INVALID`). You sent an `Authorization` header and no partner key (`EMBED_TOKEN_INVALID`)."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VALIDATION_FAILED",
          "message": "payload.tile_filters.finish.0: Input should be 'MATTE', 'GLOSSY_POLISHED', ...",
          "field": "payload.tile_filters.finish.0",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "A field is missing, unknown or has an unusable value. `field` names it."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VERIFICATION_RATE_LIMITED",
          "message": "A code was just sent. Wait a moment before asking for another.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The resend came too soon, or the mailbox reached its limit (`VERIFICATION_RATE_LIMITED`), or your daily limit for codes is used up (`RATE_LIMITED`). `Retry-After` says how long to wait."
     },
     "502": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VERIFICATION_EMAIL_FAILED",
          "message": "We couldn't send the code. Try again.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The email could not be sent. Retrying is safe."
     }
    },
    "security": [
     {
      "PartnerKey": []
     }
    ],
    "parameters": [
     {
      "name": "X-Flume-Client-IP",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "The user's own IP address: one IPv4 or IPv6 address. When sent, Flume also limits codes per IP address. Without it, only the limits per mailbox apply."
     }
    ],
    "summary": "Send a verification code",
    "description": "Emails a 6-digit verification code to a user.\n\n- Send `external_ref`, your permanent id for the user, and `email`.\n- The code is valid for 10 minutes.\n- No account or token exists until the code is confirmed.\n- Call again to resend after `resend_after_s` seconds, or to update the user's details.\n- Send the user's IP address as `X-Flume-Client-IP`. Flume then also limits codes per IP address.\n- Codes count against a daily limit per partner."
   }
  },
  "/users/confirm-verification": {
   "post": {
    "tags": [
     "Users"
    ],
    "operationId": "confirmVerification",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConfirmRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/VerifiedUser"
        }
       }
      },
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "PARTNER_KEY_INVALID",
          "message": "The API key is missing, invalid, revoked or expired.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The partner key is missing, unknown, revoked or expired (`PARTNER_KEY_INVALID`). You sent an `Authorization` header and no partner key (`EMBED_TOKEN_INVALID`)."
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "NOT_FOUND",
          "message": "No user with that email is awaiting a code. Call trigger-verification first.",
          "field": "email",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "No user of yours with that email is awaiting a code."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VERIFICATION_CODE_INVALID",
          "message": "That code didn't match. Check the digits and try again. 2 tries left.",
          "field": "code",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Wrong code (`VERIFICATION_CODE_INVALID`, the message says how many tries are left), too many wrong tries (`VERIFICATION_TRIES_EXHAUSTED`), or no live code: expired, used or never sent (`VERIFICATION_CODE_EXPIRED`)."
     }
    },
    "security": [
     {
      "PartnerKey": []
     }
    ],
    "summary": "Confirm a verification code",
    "description": "Confirms the code a user typed and returns their user access token.\n\n- Flume opens a Flume account for the user, or links the one their email already has.\n- `access_token` is returned once and has no expiry. Store it as a secret, against the user.\n- Three wrong tries burn the code. After that, or after 10 minutes, send a new one.\n- Confirming again issues a new token and stops the old one."
   }
  },
  "/users/{external_ref}/token": {
   "delete": {
    "tags": [
     "Users"
    ],
    "operationId": "revokeUserToken",
    "parameters": [
     {
      "name": "external_ref",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Your id for the user, as you sent it when the user verified."
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "PARTNER_KEY_INVALID",
          "message": "The API key is missing, invalid, revoked or expired.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The partner key is missing, unknown, revoked or expired (`PARTNER_KEY_INVALID`). You sent an `Authorization` header and no partner key (`EMBED_TOKEN_INVALID`)."
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "NOT_FOUND",
          "message": "No user with that external_ref.",
          "field": "external_ref",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "No user of yours with that external_ref."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VALIDATION_FAILED",
          "message": "payload.tile_filters.finish.0: Input should be 'MATTE', 'GLOSSY_POLISHED', ...",
          "field": "payload.tile_filters.finish.0",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "A field is missing, unknown or has an unusable value. `field` names it."
     }
    },
    "security": [
     {
      "PartnerKey": []
     }
    ],
    "summary": "Revoke a user's access token",
    "description": "Revokes a user's access token at once.\n\n- Every iframe session opened with it ends at its next call.\n- Verify the user again to issue a new token."
   }
  },
  "/filters": {
   "get": {
    "tags": [
     "Search"
    ],
    "operationId": "listFilters",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/FiltersResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "PARTNER_KEY_INVALID",
          "message": "The API key is missing, invalid, revoked or expired.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The partner key is missing, unknown, revoked or expired (`PARTNER_KEY_INVALID`). You sent an `Authorization` header and no partner key (`EMBED_TOKEN_INVALID`)."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VALIDATION_FAILED",
          "message": "payload.tile_filters.finish.0: Input should be 'MATTE', 'GLOSSY_POLISHED', ...",
          "field": "payload.tile_filters.finish.0",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "A field is missing, unknown or has an unusable value. `field` names it."
     }
    },
    "security": [
     {
      "PartnerKey": []
     }
    ],
    "summary": "List filter options",
    "description": "Returns every value each search filter accepts, with a label to show.\n\n- Build your filter menus from this call. New values then appear without a release."
   }
  },
  "/search": {
   "post": {
    "tags": [
     "Search"
    ],
    "operationId": "search",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SearchResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "IMAGE_REQUIRED",
          "message": "A search needs a photo in the `image` part.",
          "field": "image",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The request has no `image` part."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_TOKEN_INVALID",
          "message": "The user access token is missing, invalid, revoked or replaced. Verify the user again to get a new one.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The user access token is unknown, revoked or replaced by a later verification (`USER_TOKEN_INVALID`), or the partner key is invalid (`PARTNER_KEY_INVALID`)."
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_NOT_CONNECTED",
          "message": "Connect your Flume account to continue.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "No `X-Flume-User-Token` header was sent."
     },
     "413": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "IMAGE_TOO_LARGE",
          "message": "The photo is over 6 MB.",
          "field": "image",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The photo is over 6 MB."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "IMAGE_UNSUPPORTED",
          "message": "That image format is not supported. Use a JPEG, PNG or WebP.",
          "field": "image",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The photo is not a JPEG, PNG or WebP (Flume reads the bytes, not the file name), or a payload field is unusable (`VALIDATION_FAILED`, and `field` names it)."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "RATE_LIMITED",
          "message": "Today's limit of 1,000 searches is used up. It resets at 00:00 UTC.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Today's limit of 1,000 searches per partner is used up (`RATE_LIMITED`). Retry after 00:00 UTC. The `Retry-After` header says how many seconds. Or this user's own daily limit of searches is used up (`DAILY_LIMIT_REACHED`), when Flume has set one for your account. `details` then holds `kind`, `limit`, `reset_at` and `retry_after_s`."
     },
     "503": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "SEARCH_UNAVAILABLE",
          "message": "Search is not available right now.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Search is briefly unavailable. Retry with backoff."
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "multipart/form-data": {
       "schema": {
        "type": "object",
        "required": [
         "image",
         "payload"
        ],
        "properties": {
         "image": {
          "type": "string",
          "format": "binary"
         },
         "payload": {
          "$ref": "#/components/schemas/SearchPayload"
         }
        }
       },
       "encoding": {
        "payload": {
         "contentType": "application/json"
        }
       }
      }
     }
    },
    "security": [
     {
      "PartnerKey": [],
      "UserToken": []
     }
    ],
    "summary": "Search by photo",
    "description": "Returns products that look like a photo and match the filters you send.\n\n- Send `multipart/form-data` with two parts: `image` and `payload`.\n- `image`: a JPEG, PNG or WebP, up to 6 MB.\n- `payload`: JSON. `category` is required.\n- The response has two lists: `strong_matches`, then `other_similar_options`.\n- Keep `search_session_uuid`. Quotes, saves and deep links for these products need it.\n- For the next page, send the same photo and payload with `page: 2`. Each call counts as a new search and returns a new `search_session_uuid`.\n- Send `spec_unit_price` to get `saving_vs_spec` on each result.\n- Daily limit: 1,000 searches per partner."
   }
  },
  "/products/{sku_uuid}": {
   "get": {
    "tags": [
     "Products"
    ],
    "operationId": "getProduct",
    "parameters": [
     {
      "name": "sku_uuid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The product's id, from a search result."
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_TOKEN_INVALID",
          "message": "The user access token is missing, invalid, revoked or replaced. Verify the user again to get a new one.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The user access token is unknown, revoked or replaced by a later verification (`USER_TOKEN_INVALID`), or the partner key is invalid (`PARTNER_KEY_INVALID`)."
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_NOT_CONNECTED",
          "message": "Connect your Flume account to continue.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "No `X-Flume-User-Token` header was sent."
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "NOT_FOUND",
          "message": "No product with that sku_uuid.",
          "field": "sku_uuid",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Unknown sku_uuid."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VALIDATION_FAILED",
          "message": "payload.tile_filters.finish.0: Input should be 'MATTE', 'GLOSSY_POLISHED', ...",
          "field": "payload.tile_filters.finish.0",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "A field is missing, unknown or has an unusable value. `field` names it."
     }
    },
    "security": [
     {
      "PartnerKey": [],
      "UserToken": []
     }
    ],
    "summary": "Retrieve a product",
    "description": "Returns one product's photos, price, specification and shipping options."
   }
  },
  "/request-instant-quote": {
   "post": {
    "tags": [
     "Quotes"
    ],
    "operationId": "requestInstantQuote",
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "One value per user action, 1 to 255 characters. A UUID works well. A retry with the same value returns the first response."
      },
      "description": "One value per user action, 1 to 255 characters. A UUID works well. A retry with the same value returns the first response."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/QuoteRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/QuoteResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "BELOW_MINIMUM_ORDER",
          "message": "The smallest order we can quote for this product is 1,000 sq. ft.",
          "field": "quantity_sqft",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The quantity is under the product's minimum order (`BELOW_MINIMUM_ORDER`), the `Idempotency-Key` header is missing (`IDEMPOTENCY_KEY_REQUIRED`), or Flume's sales team prices this product (`NOT_INSTANTLY_QUOTABLE`)."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_TOKEN_INVALID",
          "message": "The user access token is missing, invalid, revoked or replaced. Verify the user again to get a new one.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The user access token is unknown, revoked or replaced by a later verification (`USER_TOKEN_INVALID`), or the partner key is invalid (`PARTNER_KEY_INVALID`)."
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_NOT_CONNECTED",
          "message": "Connect your Flume account to continue.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "No `X-Flume-User-Token` header was sent."
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "SESSION_NOT_FOUND",
          "message": "No search with that search_session_uuid for this user.",
          "field": "search_session_uuid",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The `sku_uuid` is unknown (`NOT_FOUND`), or the search is not this user's (`SESSION_NOT_FOUND`)."
     },
     "409": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "IDEMPOTENCY_IN_PROGRESS",
          "message": "The first request with this Idempotency-Key is still running. Retry shortly.",
          "field": "Idempotency-Key",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The first request with this Idempotency-Key is still running. Retry shortly."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "SKU_NOT_IN_SEARCH",
          "message": "This product was not a result of that search. Use the search_session_uuid of the search (or the page) that returned it.",
          "field": "sku_uuid",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The product was not a result of that search (`SKU_NOT_IN_SEARCH`), or a field is unusable (`VALIDATION_FAILED`, and `field` names it)."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "RATE_LIMITED",
          "message": "Today's limit of 200 instant quotes is used up. It resets at 00:00 UTC.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Today's limit of 200 instant quotes per partner is used up (`RATE_LIMITED`). Retry after 00:00 UTC. The `Retry-After` header says how many seconds. Or this user's own daily limit of instant quotes is used up (`DAILY_LIMIT_REACHED`), when Flume has set one for your account. `details` then holds `kind`, `limit`, `reset_at` and `retry_after_s`."
     }
    },
    "security": [
     {
      "PartnerKey": [],
      "UserToken": []
     }
    ],
    "summary": "Request an instant quote",
    "description": "Returns the delivered price of one product for a quantity and a US ZIP code.\n\n- The response lists one price per shipping option, cheapest first. Freight and sales tax are included.\n- `search_session_uuid` must be the search that returned the product.\n- The call can take up to 60 seconds. Set your HTTP read timeout to 75 seconds.\n- `READY`: `quote` holds the prices, valid until `valid_until`.\n- `FAILED`: read `failure_reason`. `TEMPORARILY_UNAVAILABLE` can mean the quote is still pricing. Poll `GET /quotes/{quote_uuid}`.\n- A shipping option is priced only when the quantity reaches its `minimum_order_sqft`.\n- Daily limit: 200 instant quotes per partner."
   }
  },
  "/quotes/{quote_uuid}": {
   "get": {
    "tags": [
     "Quotes"
    ],
    "operationId": "getQuote",
    "parameters": [
     {
      "name": "quote_uuid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The quote's id, from `POST /request-instant-quote`."
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/QuoteResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_TOKEN_INVALID",
          "message": "The user access token is missing, invalid, revoked or replaced. Verify the user again to get a new one.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The user access token is unknown, revoked or replaced by a later verification (`USER_TOKEN_INVALID`), or the partner key is invalid (`PARTNER_KEY_INVALID`)."
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_NOT_CONNECTED",
          "message": "Connect your Flume account to continue.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "No `X-Flume-User-Token` header was sent."
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "NOT_FOUND",
          "message": "No instant quote with that quote_uuid.",
          "field": "quote_uuid",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Not one of this user's instant quotes."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VALIDATION_FAILED",
          "message": "payload.tile_filters.finish.0: Input should be 'MATTE', 'GLOSSY_POLISHED', ...",
          "field": "payload.tile_filters.finish.0",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "A field is missing, unknown or has an unusable value. `field` names it."
     }
    },
    "security": [
     {
      "PartnerKey": [],
      "UserToken": []
     }
    ],
    "summary": "Retrieve an instant quote",
    "description": "Returns an instant quote by id, in the same shape as `POST /request-instant-quote`.\n\n- Use it to poll a quote that is still pricing.\n- Poll every 12 seconds for 2 minutes, then every 30 seconds until 5 minutes, then stop.\n- No daily limit is used."
   }
  },
  "/deep-links": {
   "post": {
    "tags": [
     "Deep links"
    ],
    "operationId": "createDeepLink",
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "One value per user action, 1 to 255 characters. A retry with the same value returns the first response."
      },
      "description": "One value per user action, 1 to 255 characters. A retry with the same value returns the first response."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeepLinkRequest"
       }
      }
     }
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeepLinkResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_TOKEN_INVALID",
          "message": "The user access token is missing, invalid, revoked or replaced. Verify the user again to get a new one.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The user access token is unknown, revoked or replaced by a later verification (`USER_TOKEN_INVALID`), or the partner key is invalid (`PARTNER_KEY_INVALID`)."
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "USER_NOT_CONNECTED",
          "message": "Connect your Flume account to continue.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "No `X-Flume-User-Token` header was sent."
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "SESSION_NOT_FOUND",
          "message": "No search with that search_session_uuid for this user.",
          "field": "search_session_uuid",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The search is not this user's."
     },
     "409": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "IDEMPOTENCY_IN_PROGRESS",
          "message": "The first request with this Idempotency-Key is still running. Retry shortly.",
          "field": "Idempotency-Key",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The first request with this Idempotency-Key is still running. Retry shortly."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "SKU_NOT_IN_SEARCH",
          "message": "This product was not a result of that search. Use the search_session_uuid of the search (or the page) that returned it.",
          "field": "sku_uuid",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The product was not a result of that search (`SKU_NOT_IN_SEARCH`), the quote is not `READY` (`QUOTE_NOT_READY`), or a field is unusable (`VALIDATION_FAILED`, and `field` names it)."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "RATE_LIMITED",
          "message": "Today's limit of 2,000 deep links is used up. It resets at 00:00 UTC.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Today's limit of 2,000 deep links per partner is used up (`RATE_LIMITED`). Retry after 00:00 UTC. The `Retry-After` header says how many seconds."
     }
    },
    "security": [
     {
      "PartnerKey": [],
      "UserToken": []
     }
    ],
    "summary": "Create a deep link",
    "description": "Creates a one-time link that opens the Flume app with the user signed in.\n\n- Create it when the user clicks, and open it at once. It works once, within 7 days.\n- `search_session_uuid` is required. Add `sku_uuid` to open a product from that search.\n- A replay of the same `Idempotency-Key` returns `url: null`."
   }
  },
  "/keys": {
   "get": {
    "tags": [
     "Keys"
    ],
    "operationId": "listKeys",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KeyList"
        }
       }
      },
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "PARTNER_KEY_INVALID",
          "message": "The API key is missing, invalid, revoked or expired.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The partner key is missing, unknown, revoked or expired (`PARTNER_KEY_INVALID`). You sent an `Authorization` header and no partner key (`EMBED_TOKEN_INVALID`)."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VALIDATION_FAILED",
          "message": "payload.tile_filters.finish.0: Input should be 'MATTE', 'GLOSSY_POLISHED', ...",
          "field": "payload.tile_filters.finish.0",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "A field is missing, unknown or has an unusable value. `field` names it."
     }
    },
    "security": [
     {
      "PartnerKey": []
     }
    ],
    "summary": "List keys",
    "description": "Returns your partner keys and their status. It never returns a secret."
   },
   "post": {
    "tags": [
     "Keys"
    ],
    "operationId": "rotateKey",
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "description": "A new value for each rotation."
      },
      "description": "A new value for each rotation."
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/KeyCreateRequest"
         },
         {
          "type": "null"
         }
        ]
       }
      }
     }
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KeyCreated"
        }
       }
      },
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "PARTNER_KEY_INVALID",
          "message": "The API key is missing, invalid, revoked or expired.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The partner key is missing, unknown, revoked or expired (`PARTNER_KEY_INVALID`). You sent an `Authorization` header and no partner key (`EMBED_TOKEN_INVALID`)."
     },
     "409": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "KEY_LIMIT_REACHED",
          "message": "5 keys are already active. Revoke one before issuing another.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Too many active keys."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VALIDATION_FAILED",
          "message": "payload.tile_filters.finish.0: Input should be 'MATTE', 'GLOSSY_POLISHED', ...",
          "field": "payload.tile_filters.finish.0",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "A field is missing, unknown or has an unusable value. `field` names it."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "KEY_ROTATION_RATE_LIMITED",
          "message": "A key was issued in the last 24 hours. The current key keeps working.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "Issued too recently. The current key keeps working."
     }
    },
    "security": [
     {
      "PartnerKey": []
     }
    ],
    "summary": "Rotate a key",
    "description": "Issues a new partner key and sets the key you called with to expire.\n\n- `secret` is returned once.\n- The key you called with keeps working for `overlap_days`.\n- `Idempotency-Key` is required."
   }
  },
  "/keys/{key_id}": {
   "delete": {
    "tags": [
     "Keys"
    ],
    "operationId": "revokeKey",
    "parameters": [
     {
      "name": "key_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The key to revoke, from `GET /keys`."
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "PARTNER_KEY_INVALID",
          "message": "The API key is missing, invalid, revoked or expired.",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The partner key is missing, unknown, revoked or expired (`PARTNER_KEY_INVALID`). You sent an `Authorization` header and no partner key (`EMBED_TOKEN_INVALID`)."
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "NOT_FOUND",
          "message": "No key with that id.",
          "field": "key_id",
          "request_id": "5b0f3c2e-8d41-4a6e-9f27-1c3e7a9d2b64"
         }
        }
       }
      },
      "description": "No key of yours with that `key_id`."
     },
     "409": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "LAST_ACTIVE_KEY",
          "message": "This is the only working key. Issue a replacement first.",
          "field": "key_id",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "The only working key cannot be revoked."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ErrorResponse"
        },
        "example": {
         "error": {
          "code": "VALIDATION_FAILED",
          "message": "payload.tile_filters.finish.0: Input should be 'MATTE', 'GLOSSY_POLISHED', ...",
          "field": "payload.tile_filters.finish.0",
          "request_id": "e19b8889-a63b-4000-9dbe-ffd5b9157bd5"
         }
        }
       }
      },
      "description": "A field is missing, unknown or has an unusable value. `field` names it."
     }
    },
    "security": [
     {
      "PartnerKey": []
     }
    ],
    "summary": "Revoke a key",
    "description": "Revokes a partner key at once.\n\n- You cannot revoke your only working key. Rotate first."
   }
  }
 },
 "components": {
  "schemas": {
   "AccountLink": {
    "type": "string",
    "enum": [
     "CREATED",
     "LINKED"
    ],
    "description": "How the user's Flume account was set up: `CREATED` or `LINKED`."
   },
   "ApplicationArea": {
    "enum": [
     "INTERIOR_WALL_BACKSPLASH",
     "SHOWER_WALL",
     "STEAM_SHOWER_WET_ROOM_WALL",
     "EXTERIOR_WALL_FACADE",
     "INTERIOR_DRY_FLOOR",
     "INTERIOR_WET_FLOOR",
     "SHOWER_FLOOR",
     "EXTERIOR_FLOOR_PATIO",
     "RAMP_STAIR",
     "POOL_DECK_WET_SURROUND",
     "POOL_SUBMERGED",
     "COUNTERTOP"
    ],
    "type": "string",
    "description": "An area where a tile is used."
   },
   "ApplicationAreaOut": {
    "properties": {
     "code": {
      "type": "string",
      "description": "The area's code, as `GET /filters` lists it.",
      "examples": [
       "INTERIOR_DRY_FLOOR"
      ]
     },
     "label": {
      "type": "string",
      "description": "The area's name, to show.",
      "examples": [
       "Interior Dry Floor"
      ]
     }
    },
    "type": "object",
    "required": [
     "code",
     "label"
    ],
    "description": "An area where the product can be used."
   },
   "Category": {
    "enum": [
     "TILE",
     "FLOORING"
    ],
    "type": "string",
    "description": "What a search looks for, and what a product is: `TILE` or `FLOORING` (vinyl flooring)."
   },
   "ConfirmRequest": {
    "properties": {
     "method": {
      "$ref": "#/components/schemas/VerificationMethod",
      "default": "email_code",
      "description": "The method used to send the code. `email_code` is the only method today."
     },
     "email": {
      "type": "string",
      "maxLength": 320,
      "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
      "description": "The address the code was sent to.",
      "examples": [
       "sarah.chen@example.com"
      ]
     },
     "code": {
      "type": "string",
      "pattern": "^\\d{6}$",
      "description": "The 6 digits from the email.",
      "examples": [
       "482913"
      ]
     },
     "external_ref": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 128
       },
       {
        "type": "null"
       }
      ],
      "description": "Your id for the user. Needed only when two of your users share one email.",
      "examples": [
       "u_8812"
      ]
     }
    },
    "additionalProperties": false,
    "type": "object",
    "required": [
     "email",
     "code"
    ],
    "description": "The code the user typed, and the address it was sent to."
   },
   "CropBox": {
    "properties": {
     "x": {
      "maximum": 1,
      "minimum": 0,
      "type": "number",
      "description": "The left edge, from 0 to 1."
     },
     "y": {
      "maximum": 1,
      "minimum": 0,
      "type": "number",
      "description": "The top edge, from 0 to 1."
     },
     "w": {
      "exclusiveMinimum": 0,
      "maximum": 1,
      "type": "number",
      "description": "The width, as a fraction of the photo's width."
     },
     "h": {
      "exclusiveMinimum": 0,
      "maximum": 1,
      "type": "number",
      "description": "The height, as a fraction of the photo's height."
     }
    },
    "required": [
     "x",
     "y",
     "w",
     "h"
    ],
    "type": "object",
    "description": "A part of the photo, as fractions of its width and height."
   },
   "DeepLinkRequest": {
    "properties": {
     "search_session_uuid": {
      "type": "string",
      "format": "uuid",
      "description": "One of the user's searches. Without `sku_uuid`, the link opens its results."
     },
     "sku_uuid": {
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ],
      "description": "A product to open. It must be a result of that search."
     },
     "quote_uuid": {
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ],
      "description": "An instant quote to open, with `sku_uuid`. It must be `READY` and belong to the user."
     },
     "target": {
      "anyOf": [
       {
        "type": "string",
        "enum": [
         "product",
         "search",
         "quote"
        ]
       },
       {
        "type": "null"
       }
      ],
      "description": "What the link opens: `product`, `search` or `quote`. Optional. Without it, the link opens the most specific id you send: `quote_uuid`, then `sku_uuid`, then the search. When set, it wins: `product` with a `quote_uuid` opens the product. `quote` needs `quote_uuid`, and `product` needs `sku_uuid`. Every id you send is checked, whatever `target` says."
     },
     "utm_content": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 64
       },
       {
        "type": "null"
       }
      ],
      "description": "A name for the button that asked, for your own reporting."
     },
     "redirect_uri": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 2048
       },
       {
        "type": "null"
       }
      ],
      "description": "Where Flume sends the user back to. It must be an `https` URL on a redirect host agreed with Flume."
     }
    },
    "additionalProperties": false,
    "type": "object",
    "required": [
     "search_session_uuid"
    ],
    "description": "What the link opens.",
    "examples": [
     {
      "search_session_uuid": "5f0c1d2e-8a7b-4c3d-9e1f-2a3b4c5d6e7f",
      "sku_uuid": "7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30"
     }
    ]
   },
   "DeepLinkResponse": {
    "properties": {
     "url": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The link. It works once, within 7 days. `null` when you replay an `Idempotency-Key`."
     },
     "expires_at": {
      "type": "string",
      "description": "When the link stops working, in UTC."
     }
    },
    "type": "object",
    "required": [
     "url",
     "expires_at"
    ],
    "description": "A one-time link into the Flume app.",
    "examples": [
     {
      "expires_at": "2026-10-23T09:14:22Z",
      "url": "https://app.tryflume.ai/#/l/dlk_q3Vh8yT…"
     }
    ]
   },
   "ErrorDetail": {
    "properties": {
     "code": {
      "type": "string",
      "description": "A stable code. Branch on it.",
      "examples": [
       "VALIDATION_FAILED"
      ]
     },
     "message": {
      "type": "string",
      "description": "A sentence for a person. It can change."
     },
     "field": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The request field at fault, as a dotted path, or `null`."
     },
     "request_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The request's id. Send it to Flume support."
     },
     "details": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "More about the error, when there is more. On `DAILY_LIMIT_REACHED`: `kind` (`SEARCH` or `QUOTE`), `limit`, `reset_at` (UTC) and `retry_after_s`."
     }
    },
    "type": "object",
    "required": [
     "code",
     "message"
    ],
    "description": "One error."
   },
   "ErrorResponse": {
    "properties": {
     "error": {
      "$ref": "#/components/schemas/ErrorDetail",
      "description": "The error."
     }
    },
    "type": "object",
    "required": [
     "error"
    ],
    "description": "The error envelope."
   },
   "FilterValue": {
    "properties": {
     "value": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "integer"
       }
      ],
      "description": "The value to send."
     },
     "label": {
      "type": "string",
      "description": "The text to show."
     },
     "group": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The group an application area belongs to."
     },
     "also_matches": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "The similar tile finishes this finish also finds."
     }
    },
    "type": "object",
    "required": [
     "value",
     "label"
    ],
    "description": "One value a filter accepts."
   },
   "FiltersResponse": {
    "properties": {
     "tile": {
      "$ref": "#/components/schemas/TileFilterOptions",
      "description": "Values for a `TILE` search."
     },
     "flooring": {
      "$ref": "#/components/schemas/FlooringFilterOptions",
      "description": "Values for a `FLOORING` search."
     }
    },
    "type": "object",
    "required": [
     "tile",
     "flooring"
    ],
    "description": "Every value each search filter accepts."
   },
   "Finish": {
    "enum": [
     "MATTE",
     "GLOSSY_POLISHED",
     "SATIN",
     "HONED",
     "LAPPATO_SEMI_POLISHED",
     "TEXTURED",
     "NATURAL",
     "BUSH_HAMMERED",
     "ANTI_SLIP",
     "CRACKLE"
    ],
    "type": "string",
    "description": "A tile finish."
   },
   "FlooringFilterOptions": {
    "properties": {
     "wear_layer_mil": {
      "items": {
       "$ref": "#/components/schemas/FilterValue"
      },
      "type": "array",
      "description": "Values for `flooring_filters.wear_layer_mil`."
     },
     "installation_method": {
      "items": {
       "$ref": "#/components/schemas/FilterValue"
      },
      "type": "array",
      "description": "Values for `flooring_filters.installation_method`."
     },
     "finish": {
      "items": {
       "$ref": "#/components/schemas/FilterValue"
      },
      "type": "array",
      "description": "Values for `flooring_filters.finish`."
     },
     "rigid_core": {
      "items": {
       "$ref": "#/components/schemas/FilterValue"
      },
      "type": "array",
      "description": "Values for `flooring_filters.rigid_core`."
     }
    },
    "type": "object",
    "required": [
     "wear_layer_mil",
     "installation_method",
     "finish",
     "rigid_core"
    ],
    "description": "The values the vinyl flooring filters accept."
   },
   "FlooringFilters": {
    "additionalProperties": false,
    "properties": {
     "size": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/FlooringSize"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The plank size to match."
     },
     "thickness_mm": {
      "anyOf": [
       {
        "exclusiveMinimum": 0,
        "maximum": 50,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The minimum thickness, in millimetres. Products up to 20% thinner still match.",
      "examples": [
       5
      ]
     },
     "thickness_mm_max": {
      "anyOf": [
       {
        "exclusiveMinimum": 0,
        "maximum": 50,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The maximum thickness, in millimetres.",
      "examples": [
       null
      ]
     },
     "wear_layer_mil": {
      "items": {
       "enum": [
        8,
        12,
        20,
        22,
        28
       ],
       "type": "integer"
      },
      "type": "array",
      "description": "Match any of these wear layers, in mil. `28` means 28 mil and thicker.",
      "examples": [
       [
        20,
        22
       ]
      ]
     },
     "installation_method": {
      "items": {
       "$ref": "#/components/schemas/InstallationMethod"
      },
      "type": "array",
      "description": "Match any of these installation methods.",
      "examples": [
       [
        "CLICK_LOCK"
       ]
      ]
     },
     "finish": {
      "items": {
       "$ref": "#/components/schemas/FlooringFinish"
      },
      "type": "array",
      "description": "Match any of these finishes.",
      "examples": [
       [
        "MATTE"
       ]
      ]
     },
     "eir": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "`true`: embossed in register (EIR) only. `false`: not EIR.",
      "examples": [
       null
      ]
     },
     "rigid_core": {
      "items": {
       "$ref": "#/components/schemas/RigidCore"
      },
      "type": "array",
      "description": "Match any of these core types.",
      "examples": [
       [
        "SPC"
       ]
      ]
     },
     "attached_pad": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "`true`: with an attached pad. `false`: without one.",
      "examples": [
       null
      ]
     }
    },
    "type": "object",
    "description": "Filters for a vinyl flooring search. Every field is optional."
   },
   "FlooringFinish": {
    "enum": [
     "MATTE",
     "LOW_GLOSS"
    ],
    "type": "string",
    "description": "A vinyl flooring finish."
   },
   "FlooringSize": {
    "additionalProperties": false,
    "properties": {
     "width": {
      "anyOf": [
       {
        "exclusiveMinimum": 0,
        "maximum": 10000,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The width, in `unit`.",
      "examples": [
       24
      ]
     },
     "length": {
      "anyOf": [
       {
        "exclusiveMinimum": 0,
        "maximum": 10000,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The length, in `unit`.",
      "examples": [
       48
      ]
     },
     "unit": {
      "default": "in",
      "enum": [
       "in",
       "cm",
       "mm"
      ],
      "type": "string",
      "description": "The unit of `width` and `length`."
     }
    },
    "type": "object",
    "description": "A plank or tile size. A single side is read as the width."
   },
   "GlanceRow": {
    "properties": {
     "label": {
      "type": "string",
      "description": "The fact's name.",
      "examples": [
       "Finish"
      ]
     },
     "value": {
      "type": "string",
      "description": "The fact's value.",
      "examples": [
       "Matte"
      ]
     }
    },
    "type": "object",
    "required": [
     "label",
     "value"
    ],
    "description": "One key fact about the product."
   },
   "InstallationMethod": {
    "enum": [
     "CLICK_LOCK",
     "GLUE_DOWN",
     "LOOSE_LAY"
    ],
    "type": "string",
    "description": "How a vinyl floor is installed."
   },
   "KeyCreateRequest": {
    "properties": {
     "label": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 128
       },
       {
        "type": "null"
       }
      ],
      "description": "A name for the new key, for your own records.",
      "examples": [
       "rotation 2026-Q4"
      ]
     },
     "overlap_days": {
      "type": "integer",
      "maximum": 30,
      "minimum": 0,
      "default": 7,
      "description": "How many days the key you called with keeps working."
     }
    },
    "additionalProperties": false,
    "type": "object",
    "description": "Options for the new key."
   },
   "KeyCreated": {
    "properties": {
     "key_id": {
      "type": "string",
      "description": "The key's id. Use it to revoke the key."
     },
     "prefix": {
      "type": "string",
      "description": "The start of the key. Safe to log."
     },
     "label": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The name you gave the key."
     },
     "status": {
      "$ref": "#/components/schemas/KeyStatus",
      "description": "`ACTIVE`, `EXPIRING` (replaced, and working until `expires_at`), `REVOKED` or `EXPIRED`."
     },
     "created_at": {
      "type": "string",
      "description": "When the key was issued, in UTC."
     },
     "last_used_at": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "When the key was last used, in UTC."
     },
     "expires_at": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "When a replaced key stops working, in UTC."
     },
     "secret": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The new key. Returned once. `null` when you replay an `Idempotency-Key`."
     }
    },
    "type": "object",
    "required": [
     "key_id",
     "prefix",
     "status",
     "created_at",
     "secret"
    ],
    "description": "A new partner key, with its secret."
   },
   "KeyList": {
    "properties": {
     "keys": {
      "items": {
       "$ref": "#/components/schemas/KeyOut"
      },
      "type": "array",
      "description": "Every key, newest first."
     }
    },
    "type": "object",
    "required": [
     "keys"
    ],
    "description": "Your partner keys."
   },
   "KeyOut": {
    "properties": {
     "key_id": {
      "type": "string",
      "description": "The key's id. Use it to revoke the key."
     },
     "prefix": {
      "type": "string",
      "description": "The start of the key. Safe to log."
     },
     "label": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The name you gave the key."
     },
     "status": {
      "$ref": "#/components/schemas/KeyStatus",
      "description": "`ACTIVE`, `EXPIRING` (replaced, and working until `expires_at`), `REVOKED` or `EXPIRED`."
     },
     "created_at": {
      "type": "string",
      "description": "When the key was issued, in UTC."
     },
     "last_used_at": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "When the key was last used, in UTC."
     },
     "expires_at": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "When a replaced key stops working, in UTC."
     }
    },
    "type": "object",
    "required": [
     "key_id",
     "prefix",
     "status",
     "created_at"
    ],
    "description": "One partner key. It never includes the secret."
   },
   "KeyStatus": {
    "type": "string",
    "enum": [
     "ACTIVE",
     "EXPIRING",
     "REVOKED",
     "EXPIRED"
    ],
    "description": "A partner key's status."
   },
   "LeadTime": {
    "properties": {
     "source": {
      "$ref": "#/components/schemas/SupplySourceType",
      "description": "`US_WAREHOUSE` or `OVERSEAS_DIRECT`."
     },
     "lead_time_min_days": {
      "type": "integer",
      "description": "The shortest delivery time, in days.",
      "examples": [
       14
      ]
     },
     "lead_time_max_days": {
      "type": "integer",
      "description": "The longest delivery time, in days.",
      "examples": [
       30
      ]
     }
    },
    "type": "object",
    "required": [
     "source",
     "lead_time_min_days",
     "lead_time_max_days"
    ],
    "description": "One way the product ships, with its delivery time."
   },
   "Material": {
    "enum": [
     "PORCELAIN",
     "CERAMIC"
    ],
    "type": "string",
    "description": "A tile material."
   },
   "Org": {
    "properties": {
     "external_ref": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 128
       },
       {
        "type": "null"
       }
      ],
      "description": "Your id for the firm.",
      "examples": [
       "firm_3312"
      ]
     },
     "name": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 255
       },
       {
        "type": "null"
       }
      ],
      "description": "The firm's name.",
      "examples": [
       "NY Design Co"
      ]
     },
     "website_domain": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 255
       },
       {
        "type": "null"
       }
      ],
      "description": "The firm's website domain.",
      "examples": [
       "example.com"
      ]
     }
    },
    "additionalProperties": false,
    "type": "object",
    "description": "The firm the user works at."
   },
   "PartnerQuoteStatus": {
    "type": "string",
    "enum": [
     "READY",
     "FAILED"
    ],
    "description": "`READY`: the quote has prices. `FAILED`: it has none, and `failure_reason` says why."
   },
   "ProductResponse": {
    "properties": {
     "sku_uuid": {
      "type": "string",
      "format": "uuid",
      "description": "The product's id."
     },
     "category": {
      "$ref": "#/components/schemas/Category",
      "description": "What the product is: `TILE` or `FLOORING`."
     },
     "name": {
      "type": "string",
      "description": "The product's name, written by Flume from its specification."
     },
     "as_low_as_per_sqft": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The lowest delivered price per square foot, before tax. An instant quote for a real quantity and ZIP code can be higher. `null` when `price_on_request` is `true`."
     },
     "price_on_request": {
      "type": "boolean",
      "description": "`true`: Flume's sales team prices this product, and there is no instant quote."
     },
     "image_urls": {
      "items": {
       "type": "string"
      },
      "type": "array",
      "description": "Product photos, the main one first."
     },
     "at_a_glance": {
      "items": {
       "$ref": "#/components/schemas/GlanceRow"
      },
      "type": "array",
      "description": "The key facts, in display order. Tile only. Empty for flooring."
     },
     "specification": {
      "items": {
       "$ref": "#/components/schemas/SpecGroup"
      },
      "type": "array",
      "description": "The full specification, in groups. A property the product does not state is left out."
     },
     "shipping_options": {
      "items": {
       "$ref": "#/components/schemas/ShippingOption"
      },
      "type": "array",
      "description": "The ways the product ships."
     },
     "suitable_application_areas": {
      "items": {
       "$ref": "#/components/schemas/ApplicationAreaOut"
      },
      "type": "array",
      "description": "Every area where the product can be used: floors first, then walls, then the rest. Empty for vinyl flooring, or when Flume knows none."
     }
    },
    "type": "object",
    "required": [
     "sku_uuid",
     "category",
     "name",
     "as_low_as_per_sqft",
     "price_on_request",
     "image_urls",
     "at_a_glance",
     "specification",
     "shipping_options"
    ],
    "description": "One product: photos, price, specification and shipping options.",
    "examples": [
     {
      "as_low_as_per_sqft": "6.40",
      "at_a_glance": [
       {
        "label": "Size",
        "value": "24×48″"
       },
       {
        "label": "Thickness",
        "value": "9 mm"
       },
       {
        "label": "Material",
        "value": "Porcelain"
       },
       {
        "label": "Finish",
        "value": "Matte"
       },
       {
        "label": "Slip resistance",
        "value": "DCOF > 0.42"
       }
      ],
      "category": "TILE",
      "image_urls": [
       "https://sandbox-api.tryflume.ai/partner/v1/images/eyJ…main",
       "https://sandbox-api.tryflume.ai/partner/v1/images/eyJ…2"
      ],
      "name": "Porcelain 24×48″ Matte",
      "price_on_request": false,
      "shipping_options": [
       {
        "lead_time_max_days": 30,
        "lead_time_min_days": 14,
        "minimum_order_sqft": 1000,
        "ships_from_country": "US",
        "source": "US_WAREHOUSE"
       },
       {
        "lead_time_max_days": 120,
        "lead_time_min_days": 90,
        "minimum_order_sqft": 5000,
        "ships_from_country": "ES",
        "source": "OVERSEAS_DIRECT"
       }
      ],
      "sku_uuid": "7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30",
      "specification": [
       {
        "group": "Body & surface",
        "rows": [
         {
          "label": "Actual size",
          "value": "60 × 120 cm"
         },
         {
          "label": "Edge",
          "value": "Rectified"
         }
        ]
       },
       {
        "group": "Slip resistance",
        "rows": [
         {
          "label": "DCOF",
          "test_method": "ANSI A326.3",
          "value": "> 0.42"
         }
        ]
       }
      ]
     }
    ]
   },
   "ProjectFiling": {
    "type": "string",
    "enum": [
     "FILED",
     "EXISTING",
     "NOT_FILED"
    ],
    "description": "What a search did with the project you sent."
   },
   "ProjectFilingOut": {
    "properties": {
     "external_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Your id for the project.",
      "examples": [
       "proj_7781"
      ]
     },
     "status": {
      "$ref": "#/components/schemas/ProjectFiling",
      "description": "`FILED`: this search saved the project in Flume. `EXISTING`: an earlier search saved it. `NOT_FILED`: not saved, and `reason` says why."
     },
     "reason": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ProjectNotFiled"
       },
       {
        "type": "null"
       }
      ],
      "description": "With `NOT_FILED`: `MISSING_FIELDS` (see `missing`) or `PROJECT_LIMIT_REACHED`. Otherwise `null`."
     },
     "missing": {
      "items": {
       "type": "string"
      },
      "type": "array",
      "description": "With `MISSING_FIELDS`: the fields to send next time.",
      "examples": [
       [
        "name"
       ]
      ]
     },
     "message": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "A sentence you can show the user."
     }
    },
    "type": "object",
    "required": [
     "external_ref",
     "status"
    ],
    "description": "What the search did with the `project` you sent. The search runs either way."
   },
   "ProjectNotFiled": {
    "type": "string",
    "enum": [
     "PROJECT_LIMIT_REACHED",
     "MISSING_FIELDS"
    ],
    "description": "Why a project was not saved in Flume."
   },
   "ProjectType": {
    "enum": [
     "RESIDENTIAL",
     "MULTIFAMILY",
     "COMMERCIAL",
     "HOSPITALITY",
     "HEALTHCARE",
     "EDUCATION",
     "RETAIL",
     "OTHER"
    ],
    "type": "string",
    "description": "The kind of project."
   },
   "Quote": {
    "properties": {
     "quote_uuid": {
      "type": "string",
      "format": "uuid",
      "description": "The quote's id in the user's Flume account."
     },
     "quote_number": {
      "type": "string",
      "description": "The quote's number, as the user sees it in Flume.",
      "examples": [
       "Q-7KD2-M4PA"
      ]
     },
     "sku_uuid": {
      "type": "string",
      "format": "uuid",
      "description": "The product priced."
     },
     "destination_zip": {
      "type": "string",
      "description": "The delivery ZIP code."
     },
     "currency": {
      "type": "string",
      "default": "USD",
      "description": "Always `USD`."
     },
     "created_at": {
      "type": "string",
      "description": "When the quote was priced, in UTC."
     },
     "valid_until": {
      "type": "string",
      "description": "The prices hold until this time, in UTC."
     },
     "options": {
      "items": {
       "$ref": "#/components/schemas/QuoteOption"
      },
      "type": "array",
      "description": "One entry per shipping option, cheapest `total` first."
     }
    },
    "type": "object",
    "required": [
     "quote_uuid",
     "quote_number",
     "sku_uuid",
     "destination_zip",
     "created_at",
     "valid_until",
     "options"
    ],
    "description": "A priced instant quote."
   },
   "QuoteFailure": {
    "type": "string",
    "enum": [
     "NOT_QUOTABLE",
     "TEMPORARILY_UNAVAILABLE",
     "REGION_RESTRICTED",
     "INCORRECT_DESTINATION"
    ],
    "description": "Why an instant quote has no prices."
   },
   "QuoteOption": {
    "properties": {
     "source": {
      "$ref": "#/components/schemas/SupplySourceType",
      "description": "How this option ships: `US_WAREHOUSE` or `OVERSEAS_DIRECT`."
     },
     "ships_from_country": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The 2-letter code of the country the option ships from, or `null`.",
      "examples": [
       "ES"
      ]
     },
     "lead_time_min_days": {
      "type": "integer",
      "description": "The shortest delivery time, in days."
     },
     "lead_time_max_days": {
      "type": "integer",
      "description": "The longest delivery time, in days."
     },
     "quantity_sqft": {
      "type": "string",
      "description": "The quantity priced, in square feet."
     },
     "price_per_sqft": {
      "type": "string",
      "description": "The delivered price per square foot, before tax."
     },
     "subtotal": {
      "type": "string",
      "description": "The delivered price, before tax."
     },
     "sales_tax": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The sales tax, or `null`."
     },
     "total": {
      "type": "string",
      "description": "The delivered price, including sales tax."
     }
    },
    "type": "object",
    "required": [
     "source",
     "ships_from_country",
     "lead_time_min_days",
     "lead_time_max_days",
     "quantity_sqft",
     "price_per_sqft",
     "subtotal",
     "sales_tax",
     "total"
    ],
    "description": "The delivered price for one shipping option. Show the figures as given. Do not add them up\nagain."
   },
   "QuoteRequest": {
    "properties": {
     "sku_uuid": {
      "type": "string",
      "format": "uuid",
      "description": "The product to price."
     },
     "quantity_sqft": {
      "type": "integer",
      "maximum": 10000000,
      "minimum": 1,
      "description": "The quantity, as a whole number of square feet."
     },
     "destination_zip": {
      "type": "string",
      "pattern": "^\\d{5}$",
      "description": "The US delivery ZIP code, as 5 digits."
     },
     "search_session_uuid": {
      "type": "string",
      "format": "uuid",
      "description": "The search that returned this product. Use the id from the page that listed it. Searches do not expire, so a later quote can send the same id."
     }
    },
    "additionalProperties": false,
    "type": "object",
    "required": [
     "sku_uuid",
     "quantity_sqft",
     "destination_zip",
     "search_session_uuid"
    ],
    "description": "The product, quantity and destination to price.",
    "examples": [
     {
      "destination_zip": "22102",
      "quantity_sqft": 6000,
      "search_session_uuid": "5f0c1d2e-8a7b-4c3d-9e1f-2a3b4c5d6e7f",
      "sku_uuid": "7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30"
     }
    ]
   },
   "QuoteResponse": {
    "properties": {
     "status": {
      "$ref": "#/components/schemas/PartnerQuoteStatus",
      "description": "`READY` or `FAILED`."
     },
     "failure_reason": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/QuoteFailure"
       },
       {
        "type": "null"
       }
      ],
      "description": "With `FAILED`: why there are no prices. `TEMPORARILY_UNAVAILABLE` can mean the quote is still pricing."
     },
     "quote_uuid": {
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ],
      "description": "The id to poll with. Send it to `GET /quotes/{quote_uuid}` while the quote is still pricing. Every response has it."
     },
     "quote": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Quote"
       },
       {
        "type": "null"
       }
      ],
      "description": "The prices, with `READY`. Otherwise `null`."
     }
    },
    "type": "object",
    "required": [
     "status"
    ],
    "description": "An instant quote. `READY`: `quote` holds the prices. `FAILED`: `failure_reason` says why.",
    "examples": [
     {
      "quote": {
       "created_at": "2026-10-16T09:14:22Z",
       "currency": "USD",
       "destination_zip": "22102",
       "options": [
        {
         "lead_time_max_days": 120,
         "lead_time_min_days": 90,
         "price_per_sqft": "6.40",
         "quantity_sqft": "6000.00",
         "sales_tax": "3168.00",
         "ships_from_country": "ES",
         "source": "OVERSEAS_DIRECT",
         "subtotal": "38400.00",
         "total": "41568.00"
        },
        {
         "lead_time_max_days": 30,
         "lead_time_min_days": 14,
         "price_per_sqft": "8.10",
         "quantity_sqft": "6000.00",
         "sales_tax": "4009.50",
         "ships_from_country": "US",
         "source": "US_WAREHOUSE",
         "subtotal": "48600.00",
         "total": "52609.50"
        }
       ],
       "quote_number": "Q-7KD2-M4PA",
       "quote_uuid": "9c1e4b7a-2f3d-4e5b-8a6c-7d8e9f0a1b2c",
       "sku_uuid": "7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30",
       "valid_until": "2026-10-23T09:14:22Z"
      },
      "status": "READY"
     }
    ]
   },
   "RigidCore": {
    "enum": [
     "SPC",
     "WPC"
    ],
    "type": "string",
    "description": "A vinyl flooring core type."
   },
   "SavingVsSpec": {
    "properties": {
     "percent": {
      "type": "integer",
      "description": "The saving, in percent.",
      "examples": [
       43
      ]
     },
     "label": {
      "type": "string",
      "description": "The saving as text, to show.",
      "examples": [
       "Est. 43% less than the spec"
      ]
     }
    },
    "type": "object",
    "required": [
     "percent",
     "label"
    ],
    "description": "A saving against the unit price of the product the user has now. Sent only when the saving\nis 5% or more."
   },
   "SearchResponse": {
    "properties": {
     "search_session_uuid": {
      "type": "string",
      "format": "uuid",
      "description": "The search's id. Send it when you request a quote, save an item or create a deep link for a product on this page. Every call returns a new one, page 2 included."
     },
     "total": {
      "type": "integer",
      "description": "Products across all pages, at most 50."
     },
     "strong_match_count": {
      "type": "integer",
      "description": "How many of `total` are strong matches."
     },
     "other_similar_count": {
      "type": "integer",
      "description": "How many of `total` are other similar options."
     },
     "page": {
      "type": "integer",
      "description": "The page returned."
     },
     "page_size": {
      "type": "integer",
      "description": "Products per page."
     },
     "has_more": {
      "type": "boolean",
      "description": "`true` when a later page has more products."
     },
     "strong_matches": {
      "items": {
       "$ref": "#/components/schemas/SearchResult"
      },
      "type": "array",
      "description": "Products on this page that meet every filter and look closest to the photo, best first."
     },
     "other_similar_options": {
      "items": {
       "$ref": "#/components/schemas/SearchResult"
      },
      "type": "array",
      "description": "Products on this page that look close to the photo, with some filters relaxed. They come after every strong match."
     },
     "project": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ProjectFilingOut"
       },
       {
        "type": "null"
       }
      ],
      "description": "What happened to the `project` you sent. `null` when you sent none."
     }
    },
    "type": "object",
    "required": [
     "search_session_uuid",
     "total",
     "strong_match_count",
     "other_similar_count",
     "page",
     "page_size",
     "has_more",
     "strong_matches",
     "other_similar_options"
    ],
    "description": "One page of results, in two lists: strong matches, then other similar options.",
    "examples": [
     {
      "has_more": true,
      "other_similar_count": 22,
      "other_similar_options": [
       {
        "as_low_as_per_sqft": "5.90",
        "image_url": "https://sandbox-api.tryflume.ai/partner/v1/images/eyJ…main",
        "lead_times": [
         {
          "lead_time_max_days": 30,
          "lead_time_min_days": 14,
          "source": "US_WAREHOUSE"
         },
         {
          "lead_time_max_days": 120,
          "lead_time_min_days": 90,
          "source": "OVERSEAS_DIRECT"
         }
        ],
        "material": "Porcelain",
        "more_image_urls": [
         "https://sandbox-api.tryflume.ai/partner/v1/images/eyJ…2",
         "https://sandbox-api.tryflume.ai/partner/v1/images/eyJ…3"
        ],
        "name": "Porcelain 24×48″ Natural",
        "price_on_request": false,
        "size": "24×48 in",
        "sku_uuid": "0b6f9d34-2e71-4c5a-8f10-3d9a7e2b6c41",
        "thickness": "9 mm"
       }
      ],
      "page": 1,
      "page_size": 24,
      "project": {
       "external_ref": "proj_7781",
       "missing": [],
       "status": "FILED"
      },
      "search_session_uuid": "5f0c1d2e-8a7b-4c3d-9e1f-2a3b4c5d6e7f",
      "strong_match_count": 9,
      "strong_matches": [
       {
        "as_low_as_per_sqft": "6.40",
        "image_url": "https://sandbox-api.tryflume.ai/partner/v1/images/eyJ…main",
        "lead_times": [
         {
          "lead_time_max_days": 30,
          "lead_time_min_days": 14,
          "source": "US_WAREHOUSE"
         },
         {
          "lead_time_max_days": 120,
          "lead_time_min_days": 90,
          "source": "OVERSEAS_DIRECT"
         }
        ],
        "material": "Porcelain",
        "more_image_urls": [
         "https://sandbox-api.tryflume.ai/partner/v1/images/eyJ…2",
         "https://sandbox-api.tryflume.ai/partner/v1/images/eyJ…3"
        ],
        "name": "Porcelain 24×48″ Matte",
        "price_on_request": false,
        "size": "24×48 in",
        "sku_uuid": "7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30",
        "thickness": "9 mm"
       }
      ],
      "total": 31
     }
    ]
   },
   "SearchResult": {
    "properties": {
     "sku_uuid": {
      "type": "string",
      "format": "uuid",
      "description": "The product's id."
     },
     "name": {
      "type": "string",
      "description": "The product's name, written by Flume from its specification."
     },
     "image_url": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The main product photo."
     },
     "more_image_urls": {
      "items": {
       "type": "string"
      },
      "type": "array",
      "description": "Other product photos."
     },
     "size": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The size, as text. Tile only.",
      "examples": [
       "24×48 in"
      ]
     },
     "thickness": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The thickness, as text. Tile only.",
      "examples": [
       "9 mm"
      ]
     },
     "material": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The material. Tile only.",
      "examples": [
       "Porcelain"
      ]
     },
     "as_low_as_per_sqft": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The lowest delivered price per square foot, before tax. An instant quote for a real quantity and ZIP code can be higher. `null` when `price_on_request` is `true`.",
      "examples": [
       "6.40"
      ]
     },
     "price_on_request": {
      "type": "boolean",
      "description": "`true`: Flume's sales team prices this product, and there is no instant quote."
     },
     "lead_times": {
      "items": {
       "$ref": "#/components/schemas/LeadTime"
      },
      "type": "array",
      "description": "The ways the product ships, with delivery times."
     },
     "suitable_application_areas": {
      "items": {
       "$ref": "#/components/schemas/ApplicationAreaOut"
      },
      "type": "array",
      "description": "Every area where the product can be used: floors first, then walls, then the rest. Empty for vinyl flooring, or when Flume knows none."
     },
     "saving_vs_spec": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/SavingVsSpec"
       },
       {
        "type": "null"
       }
      ],
      "description": "The saving against `spec_unit_price`, when you sent one. `null` when the saving is under 5%, or when the product costs the same or more."
     }
    },
    "type": "object",
    "required": [
     "sku_uuid",
     "name",
     "image_url",
     "more_image_urls",
     "size",
     "thickness",
     "material",
     "as_low_as_per_sqft",
     "price_on_request",
     "lead_times"
    ],
    "description": "One product in the results. `GET /products/{sku_uuid}` returns the full detail."
   },
   "ShippingOption": {
    "properties": {
     "source": {
      "$ref": "#/components/schemas/SupplySourceType",
      "description": "`US_WAREHOUSE` (stocked in the US) or `OVERSEAS_DIRECT` (shipped from the factory abroad)."
     },
     "ships_from_country": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The 2-letter code of the country the option ships from, or `null`.",
      "examples": [
       "ES"
      ]
     },
     "minimum_order_sqft": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "The smallest order this option ships, in square feet.",
      "examples": [
       5000
      ]
     },
     "lead_time_min_days": {
      "type": "integer",
      "description": "The shortest delivery time, in days.",
      "examples": [
       90
      ]
     },
     "lead_time_max_days": {
      "type": "integer",
      "description": "The longest delivery time, in days.",
      "examples": [
       120
      ]
     }
    },
    "type": "object",
    "required": [
     "source",
     "ships_from_country",
     "minimum_order_sqft",
     "lead_time_min_days",
     "lead_time_max_days"
    ],
    "description": "One way Flume can ship the product. It carries no price. An instant quote prices each\noption."
   },
   "SpecGroup": {
    "properties": {
     "group": {
      "type": "string",
      "description": "The group's heading.",
      "examples": [
       "Slip resistance"
      ]
     },
     "rows": {
      "items": {
       "$ref": "#/components/schemas/SpecRow"
      },
      "type": "array",
      "description": "The lines in the group."
     }
    },
    "type": "object",
    "required": [
     "group",
     "rows"
    ],
    "description": "One group of the specification."
   },
   "SpecRow": {
    "properties": {
     "label": {
      "type": "string",
      "description": "The property's name.",
      "examples": [
       "DCOF"
      ]
     },
     "value": {
      "type": "string",
      "description": "The property's value.",
      "examples": [
       "> 0.42"
      ]
     },
     "test_method": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "The test standard, when one is stated.",
      "examples": [
       "ANSI A326.3"
      ]
     }
    },
    "type": "object",
    "required": [
     "label",
     "value"
    ],
    "description": "One line of the specification."
   },
   "SupplySourceType": {
    "type": "string",
    "enum": [
     "OVERSEAS_DIRECT",
     "US_WAREHOUSE"
    ],
    "description": "How a product ships: `US_WAREHOUSE` (stocked in the US) or `OVERSEAS_DIRECT` (shipped from\nthe factory abroad)."
   },
   "TileFilterOptions": {
    "properties": {
     "material": {
      "items": {
       "$ref": "#/components/schemas/FilterValue"
      },
      "type": "array",
      "description": "Values for `tile_filters.material`."
     },
     "finish": {
      "items": {
       "$ref": "#/components/schemas/FilterValue"
      },
      "type": "array",
      "description": "Values for `tile_filters.finish` and `tile_filters.finish_exclude`."
     },
     "application_area": {
      "items": {
       "$ref": "#/components/schemas/FilterValue"
      },
      "type": "array",
      "description": "Values for `tile_filters.application_area`."
     }
    },
    "type": "object",
    "required": [
     "material",
     "finish",
     "application_area"
    ],
    "description": "The values the tile filters accept."
   },
   "TileFilters": {
    "additionalProperties": false,
    "properties": {
     "material": {
      "items": {
       "$ref": "#/components/schemas/Material"
      },
      "type": "array",
      "description": "Match any of these materials.",
      "examples": [
       [
        "PORCELAIN"
       ]
      ]
     },
     "finish": {
      "items": {
       "$ref": "#/components/schemas/Finish"
      },
      "type": "array",
      "description": "Match any of these finishes. Similar finishes are included: `MATTE` also finds `NATURAL`, `HONED` and `ANTI_SLIP`. `GET /filters` lists what each finish also finds.",
      "examples": [
       [
        "MATTE"
       ]
      ]
     },
     "finish_exclude": {
      "items": {
       "$ref": "#/components/schemas/Finish"
      },
      "type": "array",
      "description": "Leave these finishes out.",
      "examples": [
       [
        "GLOSSY_POLISHED"
       ]
      ]
     },
     "application_area": {
      "items": {
       "$ref": "#/components/schemas/ApplicationArea"
      },
      "type": "array",
      "description": "Where the tile is used. A product must suit every area listed.",
      "examples": [
       [
        "SHOWER_FLOOR"
       ]
      ]
     },
     "size": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/TileSize"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The tile size to match."
     },
     "thickness_mm": {
      "anyOf": [
       {
        "exclusiveMinimum": 0,
        "maximum": 500,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The minimum thickness, in millimetres. Products up to 2 mm thinner still match.",
      "examples": [
       9
      ]
     },
     "glazed": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "`true`: glazed only. `false`: unglazed only.",
      "examples": [
       true
      ]
     },
     "mosaic": {
      "default": false,
      "type": "boolean",
      "description": "`false` leaves mosaics out. `true` returns mosaics only."
     }
    },
    "type": "object",
    "description": "Filters for a tile search. Every field is optional."
   },
   "TileSize": {
    "additionalProperties": false,
    "properties": {
     "width": {
      "anyOf": [
       {
        "exclusiveMinimum": 0,
        "maximum": 10000,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The width, in `unit`.",
      "examples": [
       24
      ]
     },
     "length": {
      "anyOf": [
       {
        "exclusiveMinimum": 0,
        "maximum": 10000,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The length, in `unit`.",
      "examples": [
       48
      ]
     },
     "unit": {
      "default": "in",
      "enum": [
       "in",
       "cm",
       "mm"
      ],
      "type": "string",
      "description": "The unit of `width` and `length`."
     }
    },
    "type": "object",
    "description": "A tile size. Flume matches it loosely: sizes within about 30% count, so 24 x 48 in also\nfinds 60 x 120 cm. Send one side or both, in any order."
   },
   "TriggerVerificationRequest": {
    "properties": {
     "external_ref": {
      "type": "string",
      "maxLength": 128,
      "minLength": 1,
      "description": "Your permanent id for the user.",
      "examples": [
       "u_8812"
      ]
     },
     "email": {
      "type": "string",
      "maxLength": 320,
      "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
      "description": "Where the code goes. It is also the user's Flume sign-in address.",
      "examples": [
       "sarah.chen@example.com"
      ]
     },
     "first_name": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 128
       },
       {
        "type": "null"
       }
      ],
      "description": "The user's first name.",
      "examples": [
       "Sarah"
      ]
     },
     "last_name": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 128
       },
       {
        "type": "null"
       }
      ],
      "description": "The user's last name.",
      "examples": [
       "Chen"
      ]
     },
     "phone": {
      "anyOf": [
       {
        "type": "string",
        "maxLength": 32
       },
       {
        "type": "null"
       }
      ],
      "description": "A US phone number, in any common format.",
      "examples": [
       "+1 212 555 0147"
      ]
     },
     "org": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Org"
       },
       {
        "type": "null"
       }
      ],
      "description": "The firm the user works at."
     },
     "method": {
      "$ref": "#/components/schemas/VerificationMethod",
      "default": "email_code",
      "description": "How the user proves their email. `email_code` is the only method today."
     }
    },
    "additionalProperties": false,
    "type": "object",
    "required": [
     "external_ref",
     "email"
    ],
    "description": "The user to send a verification code to."
   },
   "UnitPrice": {
    "additionalProperties": false,
    "properties": {
     "amount": {
      "anyOf": [
       {
        "maximum": 1000000,
        "minimum": 0,
        "type": "number"
       },
       {
        "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
        "type": "string"
       }
      ],
      "description": "The price, as a decimal.",
      "examples": [
       "9.80"
      ]
     },
     "currency": {
      "maxLength": 3,
      "minLength": 3,
      "type": "string",
      "description": "The 3-letter currency code.",
      "examples": [
       "USD"
      ]
     },
     "unit": {
      "anyOf": [
       {
        "maxLength": 16,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The unit the price is for. It matches the unit of the quantity.",
      "examples": [
       "SF"
      ]
     }
    },
    "required": [
     "amount",
     "currency"
    ],
    "type": "object",
    "description": "A price for one unit, for example `{\"amount\": \"9.80\", \"currency\": \"USD\", \"unit\": \"SF\"}`."
   },
   "VerificationMethod": {
    "type": "string",
    "enum": [
     "email_code"
    ],
    "description": "How a user proves their email."
   },
   "VerificationSent": {
    "properties": {
     "external_ref": {
      "type": "string",
      "description": "Your id for the user.",
      "examples": [
       "u_8812"
      ]
     },
     "masked_email": {
      "type": "string",
      "description": "The address the code went to, masked. Safe to show the user.",
      "examples": [
       "s···@example.com"
      ]
     },
     "expires_in_s": {
      "type": "integer",
      "description": "How long the code is valid, in seconds.",
      "examples": [
       600
      ]
     },
     "resend_after_s": {
      "type": "integer",
      "description": "How long to wait before you ask for another code for this user, in seconds.",
      "examples": [
       30
      ]
     }
    },
    "type": "object",
    "required": [
     "external_ref",
     "masked_email",
     "expires_in_s",
     "resend_after_s"
    ],
    "description": "The code was sent. Show the user a code box."
   },
   "VerifiedUser": {
    "properties": {
     "external_ref": {
      "type": "string",
      "description": "Your id for the user. Check that it is the user you expect before you store the token.",
      "examples": [
       "u_8812"
      ]
     },
     "email": {
      "type": "string",
      "description": "The verified address.",
      "examples": [
       "sarah.chen@example.com"
      ]
     },
     "access_token": {
      "type": "string",
      "description": "The user access token. Returned once. Flume keeps only a hash of it.",
      "examples": [
       "ut_dev_acme_8f3kQ…"
      ]
     },
     "token_type": {
      "type": "string",
      "const": "user_token",
      "default": "user_token",
      "description": "Always `user_token`."
     },
     "verified_at": {
      "type": "string",
      "description": "When the user verified their email, in UTC."
     },
     "account": {
      "$ref": "#/components/schemas/AccountLink",
      "description": "`CREATED`: Flume opened a new Flume account with the details you sent. `LINKED`: the email already had a Flume account, and Flume linked it unchanged."
     }
    },
    "type": "object",
    "required": [
     "external_ref",
     "email",
     "access_token",
     "verified_at",
     "account"
    ],
    "description": "A verified user and their access token. Store `access_token` as a secret, against this\nuser. Send it as `X-Flume-User-Token`, with your partner key, on every call made for the\nuser. It has no expiry."
   },
   "Project": {
    "additionalProperties": false,
    "properties": {
     "external_ref": {
      "anyOf": [
       {
        "maxLength": 128,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "Your id for the project.",
      "examples": [
       "proj_7781"
      ]
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 255,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The project's name.",
      "examples": [
       "Harbor Lofts - L2"
      ]
     },
     "project_type": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ProjectType"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The kind of project.",
      "examples": [
       "MULTIFAMILY"
      ]
     },
     "city": {
      "anyOf": [
       {
        "maxLength": 128,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The project's city.",
      "examples": [
       "McLean"
      ]
     },
     "state": {
      "anyOf": [
       {
        "pattern": "^[A-Z]{2}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The US state, as 2 capital letters.",
      "examples": [
       "VA"
      ]
     },
     "destination_zip": {
      "anyOf": [
       {
        "pattern": "^\\d{5}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The ZIP code the material is delivered to.",
      "examples": [
       "22102"
      ]
     },
     "estimated_area_sqft": {
      "anyOf": [
       {
        "maximum": 10000000,
        "minimum": 1,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The project's total area, in square feet.",
      "examples": [
       2400
      ]
     },
     "unit_count": {
      "anyOf": [
       {
        "maximum": 1000000,
        "minimum": 1,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The number of homes, units or rooms.",
      "examples": [
       48
      ]
     },
     "target_install_date": {
      "anyOf": [
       {
        "format": "date",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "When installation is planned.",
      "examples": [
       "2027-03-01"
      ]
     }
    },
    "type": "object",
    "description": "The project a search belongs to. Every field is optional, and none changes the results.\n\nSend `external_ref` and `name`, and Flume saves the project in the user's Flume account.\nLater searches with the same `external_ref` are filed under it, and so are their instant\nquotes. The response's `project` says what happened."
   },
   "SearchPayload": {
    "additionalProperties": false,
    "properties": {
     "project": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Project"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The project to file the search under."
     },
     "category": {
      "$ref": "#/components/schemas/Category",
      "description": "What to search for: `TILE` or `FLOORING` (vinyl flooring). Send the filters for that category only."
     },
     "tile_filters": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/TileFilters"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "Filters for a `TILE` search."
     },
     "flooring_filters": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/FlooringFilters"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "Filters for a `FLOORING` search."
     },
     "page": {
      "default": 1,
      "maximum": 50,
      "minimum": 1,
      "type": "integer",
      "description": "The page to return. A search finds at most 50 products."
     },
     "page_size": {
      "default": 24,
      "maximum": 24,
      "minimum": 1,
      "type": "integer",
      "description": "Products per page. Use the same value for every page of one search."
     },
     "crop_box": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/CropBox"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The part of the photo to search on."
     },
     "spec_unit_price": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/UnitPrice"
       },
       {
        "type": "null"
       }
      ],
      "default": null,
      "description": "The unit price of the product the user has now. When sent, each result carries `saving_vs_spec`. Only USD per `SF` gives a saving."
     }
    },
    "required": [
     "category"
    ],
    "type": "object",
    "description": "The `payload` part of a search, sent beside the photo.",
    "examples": [
     {
      "category": "TILE",
      "page": 1,
      "page_size": 24,
      "project": {
       "city": "McLean",
       "destination_zip": "22102",
       "estimated_area_sqft": 2400,
       "external_ref": "proj_7781",
       "name": "Harbor Lofts - L2",
       "project_type": "MULTIFAMILY",
       "state": "VA",
       "target_install_date": "2027-03-01",
       "unit_count": 48
      },
      "tile_filters": {
       "application_area": [
        "SHOWER_FLOOR"
       ],
       "finish": [
        "MATTE"
       ],
       "finish_exclude": [
        "GLOSSY_POLISHED"
       ],
       "material": [
        "PORCELAIN"
       ],
       "mosaic": false,
       "size": {
        "length": 48,
        "unit": "in",
        "width": 24
       },
       "thickness_mm": 9
      }
     },
     {
      "category": "FLOORING",
      "flooring_filters": {
       "installation_method": [
        "CLICK_LOCK"
       ],
       "rigid_core": [
        "SPC"
       ],
       "size": {
        "length": 48,
        "unit": "in",
        "width": 7
       },
       "wear_layer_mil": [
        20,
        22
       ]
      }
     }
    ]
   }
  },
  "securitySchemes": {
   "PartnerKey": {
    "type": "apiKey",
    "in": "header",
    "name": "X-Flume-Partner-Key",
    "description": "Your partner key. Send it on every call."
   },
   "UserToken": {
    "type": "apiKey",
    "in": "header",
    "name": "X-Flume-User-Token",
    "description": "The user's access token. Send it with your partner key on every call made for a user."
   }
  }
 },
 "tags": [
  {
   "name": "Users",
   "description": "Open the Flume iframe for one user, one project and one item."
  },
  {
   "name": "Search",
   "description": "Verify a user's email, hold their access token, revoke it."
  },
  {
   "name": "Products",
   "description": "Decide what an item is, list the filters, search by photo."
  },
  {
   "name": "Quotes",
   "description": "One product's photos, price, specification and shipping options."
  },
  {
   "name": "Deep links",
   "description": "The delivered price of a product for a quantity and a US ZIP code."
  },
  {
   "name": "Keys",
   "description": "The payload you map into your own records, and your report on it."
  }
 ],
 "x-error-codes": [
  "BELOW_MINIMUM_ORDER",
  "CONNECT_CODE_INVALID",
  "DAILY_LIMIT_REACHED",
  "EMBED_TOKEN_INVALID",
  "IDEMPOTENCY_IN_PROGRESS",
  "IDEMPOTENCY_KEY_REQUIRED",
  "IDEMPOTENCY_KEY_REUSED",
  "IMAGE_REQUIRED",
  "IMAGE_TOO_LARGE",
  "IMAGE_UNSUPPORTED",
  "INTERNAL",
  "KEY_LIMIT_REACHED",
  "KEY_ROTATION_RATE_LIMITED",
  "LAST_ACTIVE_KEY",
  "NOT_FOUND",
  "NOT_INSTANTLY_QUOTABLE",
  "PARTNER_KEY_INVALID",
  "QUOTE_NOT_READY",
  "RATE_LIMITED",
  "SEARCH_UNAVAILABLE",
  "SESSION_NOT_FOUND",
  "SKU_NOT_IN_SEARCH",
  "USER_ACCOUNT_CLOSED",
  "USER_NOT_CONNECTED",
  "USER_TOKEN_INVALID",
  "VALIDATION_FAILED",
  "VERIFICATION_CODE_EXPIRED",
  "VERIFICATION_CODE_INVALID",
  "VERIFICATION_EMAIL_FAILED",
  "VERIFICATION_RATE_LIMITED",
  "VERIFICATION_TRIES_EXHAUSTED"
 ]
}
