# Table of Contents - [Request Standards | Etsy Open API v3](#request-standards-etsy-open-api-v3) - [URL Syntax | Etsy Open API v3](#url-syntax-etsy-open-api-v3) - [Get help | Etsy Open API v3](#get-help-etsy-open-api-v3) - [Tutorials Overview | Etsy Open API v3](#tutorials-overview-etsy-open-api-v3) - [Definitions | Etsy Open API v3](#definitions-etsy-open-api-v3) - [Authentication | Etsy Open API v3](#authentication-etsy-open-api-v3) - [Webhooks | Etsy Open API v3](#webhooks-etsy-open-api-v3) - [Fulfillment Tutorial | Etsy Open API v3](#fulfillment-tutorial-etsy-open-api-v3) - [Rate Limits | Etsy Open API v3](#rate-limits-etsy-open-api-v3) - [Multi Personalization Migration Guide | Etsy Open API v3](#multi-personalization-migration-guide-etsy-open-api-v3) - [Examples for the Endpoint Migration Period | Etsy Open API v3](#examples-for-the-endpoint-migration-period-etsy-open-api-v3) - [Processing Profiles Migration | Etsy Open API v3](#processing-profiles-migration-etsy-open-api-v3) - [Endpoint Migration (backwards compatible) | Etsy Open API v3](#endpoint-migration-backwards-compatible-etsy-open-api-v3) - [Multiple + New Question Type Support | Etsy Open API v3](#multiple-new-question-type-support-etsy-open-api-v3) - [Examples for the Multiple + New Questions Type Support Period | Etsy Open API v3](#examples-for-the-multiple-new-questions-type-support-period-etsy-open-api-v3) - [Quick Start Tutorial | Etsy Open API v3](#quick-start-tutorial-etsy-open-api-v3) - [Etsy Open API v3 | Etsy Open API v3](#etsy-open-api-v3-etsy-open-api-v3) - [Reference | Etsy Open API v3](#reference-etsy-open-api-v3) - [Shop Management Tutorial | Etsy Open API v3](#shop-management-tutorial-etsy-open-api-v3) - [Listings Tutorial | Etsy Open API v3](#listings-tutorial-etsy-open-api-v3) - [Payments Tutorial | Etsy Open API v3](#payments-tutorial-etsy-open-api-v3) - [Authentication | Etsy Open API v3](#authentication-etsy-open-api-v3) --- # Request Standards | Etsy Open API v3 Etsy API endpoints are accessible at URLs starting with `https://api.etsy.com/v3/` or `https://openapi.etsy.com/v3/`. The two hostnames are equivalent and you can use either. Throughout this document we use `api.etsy.com` but openapi.etsy.com may be substituted instead. Making Requests[#](https://developers.etsy.com/documentation/essentials/requests/#making-requests "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------- Every request to a v3 endpoint must include: | Category | Element | Code | Description | | --- | --- | --- | --- | | endpoint | protocol | `https://` | Etsy Open API endpoints require SSL/TLS requests which must use an `https://` prefix. | | endpoint | URL | `api.etsy.com/v3/` | Etsy API endpoints are accessible at URLs starting with `https://api.etsy.com/v3/`. | | header | API key | `x-api-key:` ... | Your Etsy App API Key _keystring_ and _shared secret_, separated by a colon (`:`), which you can find in [Your Apps](https://www.etsy.com/developers/your-apps)
. | | header | oauth token | `Authorization: Bearer` ... | Any request that requires an oauth2 scope (e.g., `listings_w`) requires an authorization header. The value following `Bearer` combines a numeric user id with an oauth2 token, separted by a period (.). See [Authentication](https://developers.etsy.com/documentation/essentials/requests/authentication)
for details. | For example, if your * client ID is `exJeyZtXODeekHfX8VRgMQ` * shared secret is `a1b2c3d4e5` * numeric user ID is `12345678` * access token is `VJTv9qyjwJbYlARxdFmEEQ` the following is a valid request: curl --request GET 'https://api.etsy.com/v3/application/listings?state=active' \\ \--header 'x-api-key: exJeyZtXODeekHfX8VRgMQ:a1b2c3d4e5' \\ \--header 'authorization: Bearer 12345678.VJTv9qyjwJbYlARxdFmEEQ' \\ Copy Encoding[#](https://developers.etsy.com/documentation/essentials/requests/#encoding "Direct link to heading") -------------------------------------------------------------------------------------------------------------- All network communication with Open API v3 uses UTF-8 encoding. When creating HTTP requests for a REST API application, specify UTF-8 encoding support. For example, to set the UTF-8 encoding support in an HTTP header for a POST request, include charset=utf-8 in the content-type field, as shown in the following code: POST /v3/application/shops/12345/listings HTTPS/1.3 Host: api.etsy.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Copy When creating application code for a REST API application, provide UTF-8 encoding support using the language-specific content type settings. For example, to set the content type to UTF-8 in a Java HttpURLConnection object called `conn`, use the following code: conn.setRequestProperty("contentType", "application/json; charset=utf-8"); Copy * [Making Requests](https://developers.etsy.com/documentation/essentials/requests/#making-requests) * [Encoding](https://developers.etsy.com/documentation/essentials/requests/#encoding) --- # URL Syntax | Etsy Open API v3 The URL for any Open API v3 request determines which specific resource or collection of resources services the request. Open API v3 URLs have the following syntax: https://api.etsy.com/v3/application/\[?{&}\] Copy where * `https://api.etsy.com/v3/application/` is the default context root and directory for accessing REST API resources. * `` is the name of the REST API resource, all of which are listed in [API reference](https://developers.etsy.com/documentation/reference) * `?` specifies a parameter name and value pair that a request accepts. The endpoint definitions provide details on which parameters to use for each request. For example, in https://api.etsy.com/v3/application/listings?state=active Copy * `https://api.etsy.com/v3/application/` is the default context root and directory for accessing REST API resources. * `listings` is the name of the shop listings REST API resource, described in the [getListingsByShop](https://developers.etsy.com/documentation/reference/#operation/getListingsByShop) endpoint reference. * `?state=active` is a state parameter to filter the listings results. Asset ID Parameters[#](https://developers.etsy.com/documentation/essentials/urlsyntax#asset-id-parameters "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------ Resource paths in a URL can contain the unique IDs of Etsy assets such as shops, listings, transactions, receipts, images, etc. For example, you would use the following URL pattern to send requests to the [delete listing image](https://developers.etsy.com/documentation/reference/#operation/deleteListingImage) endpoint: DELETE https://api.etsy.com/v3/application/shop/{shop\_id}/listings/{listing\_id}/images/{listing\_image\_id} Copy Where the `{shop_id}`, `{listing_id}`, and `{listing_image_id}` parameters must be replaced by specific IDs identifying the shop, listing, and listing image to delete. Resource path parameters must appear in the URL; applications cannot send them in the HTTP Header and all ID parameters listed in the URL pattern must be present. Parameter Types[#](https://developers.etsy.com/documentation/essentials/urlsyntax#parameter-types "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------- Many API methods take one or more parameters, either as query parameters of the URL itself, or as POST parameters in the HTTP header. The documentation for each method references these standard types: | Param Type | Meaning | | --- | --- | | Array of <_type_\> | A list of values, separated by commas (","). Do not include parentheses or brackets. Each value must be a valid instance of _type_. | | boolean | A logical true or false value. May be passed to API requests as the strings "true" or "false" or "1" and "0". In JSON output, symbolic constants are used. | | Enum: _`values`_ | A predefined list of string values, for example `"oz"`, `"lb"`, `"g"`, and `"kg"` Assigning any value not in the list results in an error. | | integer | A whole number value. | | number <_type_\> | A number with or without a decimal point. Represented in output as a string, to avoid precision errors. Values must be a valid instance of _type_. | | Nullable | Accepts `null` as a value. | | string | Any string. | | string <_type_\> | A string representing something other than text. For example, if _type_ is `binary`, the string represents an image or if _type_ is `ISO 3166-1 alpha-2` the string is a country code. | Standard Parameters[#](https://developers.etsy.com/documentation/essentials/urlsyntax#standard-parameters "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------ Here is a list of standard parameters that are accepted by many or all API methods: | Parameter | Type | Meaning | | --- | --- | --- | | `x-api-key` | string | Your Etsy App API Key _keystring_ and _shared secret_, separated by a colon (`:`), which you can find in [Your Apps](https://www.etsy.com/developers/your-apps)
. Required for all endpoint requests. **Should be passed as a header** | | `limit` | integer | Specifies the maximum number of records to return for a request that returns multiple results. The default value is 25. | | `offset` | integer | Skips the first N records before returning results. Combine with `limit` for pagination. The default value is 0. | Pagination[#](https://developers.etsy.com/documentation/essentials/urlsyntax#pagination "Direct link to heading") ------------------------------------------------------------------------------------------------------------------ The minimum and default records returned per call is 25, and the maximum number that can be returned is 100. We provide `limit` and `offset` parameters to allow navigation through larger data sets. Responses include a count field, which specifies the total number of records available via pagination. For performance reasons, the offset parameter is limited to a maximum value of 12000. The `count` property in the response body will provide the total number of records without the `limit` applied. Here's an example of sequential requests to paginate through the most recent 300 listings, 50 at a time: https://api.etsy.com/v3/application/listings?state=active&limit=50&offset=0 https://api.etsy.com/v3/application/listings?state=active&limit=50&offset=50 https://api.etsy.com/v3/application/listings?state=active&limit=50&offset=100 https://api.etsy.com/v3/application/listings?state=active&limit=50&offset=150 https://api.etsy.com/v3/application/listings?state=active&limit=50&offset=200 https://api.etsy.com/v3/application/listings?state=active&limit=50&offset=250 Copy * [Asset ID Parameters](https://developers.etsy.com/documentation/essentials/urlsyntax#asset-id-parameters) * [Parameter Types](https://developers.etsy.com/documentation/essentials/urlsyntax#parameter-types) * [Standard Parameters](https://developers.etsy.com/documentation/essentials/urlsyntax#standard-parameters) * [Pagination](https://developers.etsy.com/documentation/essentials/urlsyntax#pagination) --- # Get help | Etsy Open API v3 * If you have a suggestion for our new API or documentation, you can discuss with other Etsy Open API developers on [Github Discussions](https://github.com/etsy/open-api/discussions) . * Similarly, if you suspect you’ve found a bug, please report it on [Github Discussions](https://github.com/etsy/open-api/discussions) . * If you believe something is wrong with your application, please contact us at [developers@etsy.com](mailto:developers@etsy.com) . --- # Tutorials Overview | Etsy Open API v3 * [Quick Start](https://developers.etsy.com/documentation/tutorials/quickstart) * [Fulfillment](https://developers.etsy.com/documentation/tutorials/fulfillment) * [Listings](https://developers.etsy.com/documentation/tutorials/listings) * [Shop Management](https://developers.etsy.com/documentation/tutorials/shopmanagement) * [Payments](https://developers.etsy.com/documentation/tutorials/payments) --- # Definitions | Etsy Open API v3 The following definitions will help with the OpenAPI reference section to understand what some of the objects and options mean. This is not an exhaustive list, but rather a list of requested clarifications. State Field Possible Values[#](https://developers.etsy.com/documentation/essentials/definitions#state-field-possible-values "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------ In the [ShopListing](https://developers.etsy.com/documentation/reference#tag/ShopListing) endpoints there is a field called `state` with these potential values: | Value | Meaning | | --- | --- | | `active` | Currently active listing that has at least one quantity and is has not expired. | | `inactive` or `edit` | A listing that once was, but is no longer active and is ready for modifications. | | `sold_out` | A once active listing that no longer has any available quantity. | | `draft` | A new listing that has yet to be promoted to active state. | | `expired` | A once active listing that has reached it's ending date and was not set to auto renew. | Money Object[#](https://developers.etsy.com/documentation/essentials/definitions#money-object "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------ A `money` object represents a price for a listing in a specific currency. The money object contains the following fields: | Field Name | Meaning | | --- | --- | | `amount` | This is the base amount by which the currency can not be divided further. For instance, in United States dollars, the base value is one penny or `1`. So a listing for five dollars US, would be 500 pennies. | | `divisor` | This is the number used to divide the amount to get the currency value. So a listing for 500 in the amount, will be divided by 100 pennies to come up with 5 dollars. | | `currency_code` | This is the 3 letter code for a given currency, such as `USD` for United States Dollar or `CAD` for Canadian Dollar. | Order Status Values[#](https://developers.etsy.com/documentation/essentials/definitions#order-status-values "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------- When retrieving receipts in the OpenAPI, an order (AKA receipt) can have one of the following status values: | Value | Meaning | | --- | --- | | `open` | The order has been created, but payment has not yet been submitted. This is a legacy value and was used when sellers were accepting direct payments and not using Etsy checkout. | | `paid` | The order has been created and paid for and is ready for shipping. | | `completed` | The order has been shipped and is considered complete. | | `payment processing` | The order has been created and payment data submitted, but has not been fully processed. | | `canceled` | The order was canceled. | * [State Field Possible Values](https://developers.etsy.com/documentation/essentials/definitions#state-field-possible-values) * [Money Object](https://developers.etsy.com/documentation/essentials/definitions#money-object) * [Order Status Values](https://developers.etsy.com/documentation/essentials/definitions#order-status-values) --- # Authentication | Etsy Open API v3 Etsy's Open API supports OAuth 2.0 [Authorization Code Grants](https://tools.ietf.org/html/rfc6749#page-24) to generate OAuth tokens for app security. Authorization code grants require users to approve access, which generates an authorization code an app includes in a token request (`https://api.etsy.com/v3/public/oauth/token`) from the [OAuth resource](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) . [OAuth 2.0](https://tools.ietf.org/html/rfc6749) is fairly well-standardized, so this document focuses on Etsy’s specific implementation of OAuth2. Requesting an OAuth Token[#](https://developers.etsy.com/documentation/essentials/authentication#requesting-an-oauth-token "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------------------------------- Gather the following information before starting the **authorization code** grant flow: 1. Your Etsy App API Key _keystring_, which you can find in [Your Apps](https://www.etsy.com/developers/your-apps) . 2. A _callback URL_ your app uses to receive the authorization code. Typically, this is a page or script that starts the token request using the authorization code, and therefore must implement TLS and use an `https://` prefix. See [Redirect URIs](https://developers.etsy.com/documentation/essentials/authentication#redirect-uris) below. 3. The _scopes_ your application requires to use specific endpoints. The [Open API Reference](https://developers.etsy.com/documentation/reference) lists the authorizations required to use each endpoint. For example, the endpoint to [create a listing](https://developers.etsy.com/documentation/reference#operation/createDraftListing) requires an oauth2 token with `listings_w` scope. See [Scopes](https://developers.etsy.com/documentation/essentials/authentication#scopes) below. 4. A _state_ string, similar to a [strong password](https://techjury.net/blog/how-to-create-a-strong-password) , which protects against [Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery) exploits. 5. A _code verifier_ and generated _code challenge_ proof key for code exchange (PKCE) pair required in the token request and authorization code request respectively. See [PKCE](https://developers.etsy.com/documentation/essentials/authentication#proof-key-for-code-exchange-pkce) below. ### Step 1: Request an Authorization Code[#](https://developers.etsy.com/documentation/essentials/authentication#step-1-request-an-authorization-code "Direct link to heading") To begin the flow, direct the user to `https://www.etsy.com/oauth/connect` with a GET request including the following URL parameters: | Parameter Name | Description | | --- | --- | | `response_type` | Must always be the value `code` (no quotes). | | `client_id` | An Etsy App API Key _keystring_ for the app. | | `redirect_uri` | A URI your app uses to receive the authorization code or error message; see [Redirect URIs](https://developers.etsy.com/documentation/essentials/authentication#redirect-uris)
below. The URL must have the `https://` prefix or the request will fail. | | `scope` | A URL-encoded, space-separated list of one or more scopes (e.g., `shops_r%20shops_w`); see [Scopes](https://developers.etsy.com/documentation/essentials/authentication#scopes)
below. | | `state` | The state parameter must be non-empty and should be a single-use token generated specifically for a given request. It is important that the state parameter is impossible to guess, associated with a specific request, and used once. Use _state_ for [CSRF protection](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
. | | `code_challenge` | The PKCE _code challenge_ SHA256-image of a random value for this request flow; see [PKCE](https://developers.etsy.com/documentation/essentials/authentication#proof-key-for-code-exchange-pkce)
below. | | `code_challenge_method` | Must always be the value `S256` (no quotes). | For example, to request an authorization code for an Etsy app with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff`, initiate a GET request with the following URL: https://www.etsy.com/oauth/connect? response\_type=code &redirect\_uri=https://www.example.com/some/location &scope=transactions\_r%20transactions\_w &client\_id=1aa2bb33c44d55eeeeee6fff&state=superstate &code\_challenge=DSWlW2Abh-cf8CeLL8-g3hQ2WQyYdKyiu83u\_s7nRhI &code\_challenge\_method=S256 Copy where: * `response_type=code` is required to request an authorization code. * `redirect_uri=https://www.example.com/some/location` directs etsy to send an authorization code response to `https://www.example.com/some/location`. * `scope=transactions_r%20transactions_w` adds read and write access to transactions in the authorization _scope_ for the request, which is required to [request shop receipts](https://developers.etsy.com/documentation/reference#operation/getShopReceipts) . see [Scopes](https://developers.etsy.com/documentation/essentials/authentication#scopes) below. * `client_id=1aa2bb33c44d55eeeeee6fff` is an API Key _keystring_ for the app. * `state=superstate` assigns the _state_ string to `superstate` which Etsy.com should return with the authorization code * `code_challenge=DSWlW2Abh-cf8CeLL8-g3hQ2WQyYdKyiu83u_s7nRhI` is the PKCE _code challenge_ generated from the _code verifier_ `vvkdljkejllufrvbhgeiegrnvufrhvrffnkvcknjvfid`, which must be in the OAuth token request with the authorization code. * `code_challenge_method=S256` is required to correctly interpret the _code\_challenge_. ### Step 2: Grant Access[#](https://developers.etsy.com/documentation/essentials/authentication#step-2-grant-access "Direct link to heading") If the authorization code request is valid, Etsy.com responds by prompting an Etsy.com user (typically the app user) to grant the application access the requested scopes. ![OAuth2 authorization confirmation page](https://img0.etsystatic.com/site-assets/open-api/oauth2-authorize.png) If the user grants access, Etsy.com sends a request back to the app's `redirect_uri` with the following `GET` parameters: | Parameter Name | Description | | --- | --- | | `state` | The _state_ parameter, exactly as set in the authorization request | | `code` | An OAuth _authorization code_ required to request an OAuth token | For example, the following response indicates that the user grants access and supplies an authorization code: https://www.example.com/some/location? code=bftcubu-wownsvftz5kowdmxnqtsuoikwqkha7\_4na3igu1uy-ztu1bsken68xnw4spzum8larqbry6zsxnea4or9etuicpra5zi &state=superstate Copy Before using an _authorization code_, validate that the _state_ string in the response matches the _state_ sent with the authorization code request. If they do not match, halt authentication as the request is vulnerable to CSRF attacks. If they match, make a note never to use that _state_ again, and make your next authorization code request with a new _state_ string. #### Errors[#](https://developers.etsy.com/documentation/essentials/authentication#errors "Direct link to heading") If the user does not consent, or there is some other error (e.g. a missing parameter), Etsy.com sends a response to the specified `redirect_uri` with the following `GET` parameters: | Parameter Name | Description | | --- | --- | | `state` | The _state_ parameter, exactly as set in the authorization request | | `error` | An error code from [RFC 6749](https://tools.ietf.org/html/rfc6749#section-5.2) | | `error_description` | A human-readable explanation of the error (always in English) | | `error_uri` | (Optional) A URL with more information about the error. | ### Step 3: Request an Access Token[#](https://developers.etsy.com/documentation/essentials/authentication#step-3-request-an-access-token "Direct link to heading") Request an OAuth access token using the _authorization code_ in a POST request to the Etsy Open API `/oauth/token` resource. Most requests to the Etsy Open API require this access token, which has a functional life of 1 hour. The Etsy Open API delivers a [refresh token](https://developers.etsy.com/documentation/essentials/authentication#Refreshing-an-OAuth-Token) with the access token, which you can use to obtain a new access token through the [refresh\_token grant](https://tools.ietf.org/html/rfc6749#section-6) , and has a longer functional lifetime (90 days). To obtain an access token, make a POST request to `https://api.etsy.com/v3/public/oauth/token` with the following parameters in the request body in `application/x-www-form-urlencoded` format: | Parameter Name | Description | | --- | --- | | `grant_type` | Must always be the value `authorization_code` | | `client_id` | An Etsy App API Key _keystring_ for the app. | | `redirect_uri` | The same `redirect_uri` value used in the prior authorization code request. | | `code` | The _authorization code_ sent back from Etsy.com after [granting access](https://developers.etsy.com/documentation/essentials/authentication#step-2-grant-access)
. | | `code_verifier` | The PKCE _code verifier_ preimage of the `code_challenge` used in the prior authorization code request; see [PKCE](https://developers.etsy.com/documentation/essentials/authentication#proof-key-for-code-exchange-pkce)
below. | For example, to request access for an Etsy app with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff`, initiate a POST request: https://api.etsy.com/v3/public/oauth/token? grant\_type=authorization\_code &client\_id=1aa2bb33c44d55eeeeee6fff &redirect\_uri=https://www.example.com/some/location &code=bftcubu-wownsvftz5kowdmxnqtsuoikwqkha7\_4na3igu1uy-ztu1bsken68xnw4spzum8larqbry6zsxnea4or9etuicpra5zi &code\_verifier=vvkdljkejllufrvbhgeiegrnvufrhvrffnkvcknjvfid Copy where: * `grant_type=authorization_code` is required to request an OAuth token in an authorization token grant flow. * `client_id=1aa2bb33c44d55eeeeee6fff` is an API Key _keystring_ for the app. * `redirect_uri=https://www.example.com/some/location` directs etsy to send the access token response to `https://www.example.com/some/location`. * `code=bftcubu-wownsvftz5kowdmxnqtsuoikwqkha7_4na3igu1uy-ztu1bsken68xnw4spzum8larqbry6zsxnea4or9etuicpra5zi` is the authorization code sent from Etsy.com after the user grants access * `code_verifier=vvkdljkejllufrvbhgeiegrnvufrhvrffnkvcknjvfid` is the PKCE _code verifier_ used to generate the _code challenge_ `DSWlW2Abh-cf8CeLL8-g3hQ2WQyYdKyiu83u_s7nRhI`, which we used in the authorization code request. The Etsy Open API responds to an authentic request for an OAuth token with the following information in JSON format: { "access\_token": "12345678.O1zLuwveeKjpIqCQFfmR-PaMMpBmagH6DljRAkK9qt05OtRKiANJOyZlMx3WQ\_o2FdComQGuoiAWy3dxyGI4Ke\_76PR", "token\_type": "Bearer", "expires\_in": 3600, "refresh\_token": "12345678.JNGIJtvLmwfDMhlYoOJl8aLR1BWottyHC6yhNcET-eC7RogSR5e1GTIXGrgrelWZalvh3YvvyLfKYYqvymd-u37Sjtx" } Copy where: * `access_token` is the OAuth grant token with a user id numeric prefix (`12345678` in the example above), which is the internal `user_id` of the Etsy.com user who grants the application access. The V3 Open API requires the combined user id prefix and OAuth token as formatted in this parameter to authenticate requests. * * * NOTE: This numeric OAuth `user_id` is only available from the authorization code grant flow * * * * `token_type` is always `Bearer` which indicates that the OAuth token is a bearer token. * `expires_in` is the valid duration of the OAuth token in seconds from the moment it is granted; 3600 seconds is 1 hour. * `refresh_token` is the OAuth code to request a refresh token with a user id numeric prefix (`12345678` in the example). Use this for a refresh grant access request for a fresh OAuth token without requesting access from the user/seller an additional time. Redirect URIs[#](https://developers.etsy.com/documentation/essentials/authentication#redirect-uris "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------- All `redirect_uri` parameter values must match a precise _callback URL_ string registered with Etsy. These values can be provided by editing your application at [etsy.com/developers/your-apps](https://www.etsy.com/developers/your-apps) . Authorization code or token requests with unregistered or non-matching `redirect_uri` values send an error to the user and Etsy.com does **not** redirect the user back to your app. URL matching is case-sensitive and is specifically the URL established when you registered. For example, if your registered redirect URL is `https://www.example.com/some/location`, the following strings **fail** to match: * `http://www.example.com/some/location` (http, not https) * `https://www.example.com/some/location/` (additional trailing slash) * `https://www.example.com/some/location?` (additional trailing question mark) * `Https://www.example.com/some/location` (uppercase H in https) * `https://example.com/some/location` (no www subdomain) Scopes[#](https://developers.etsy.com/documentation/essentials/authentication#scopes "Direct link to heading") --------------------------------------------------------------------------------------------------------------- Methods and fields in the Etsy API are tagged with "permission scopes" that control which operations an app can perform and which data an app can read with a given set of credentials. Scopes are the permissions you request from the user, and the access token proves you have permission to act from that user. The following scopes are available at this time, though are subject to change. The availability of a scope does not necessarily imply the existence of an endpoint to perform that action. Each API endpoint may require zero, one, or more scopes for access. Consult the [Open API Reference](https://developers.etsy.com/documentation/reference) to determine the scopes required for each specific endpoint. | Name | Description | | --- | --- | | `address_r` | Read a member's shipping addresses. | | `address_w` | Update and delete a member's shipping address. | | `billing_r` | Read a member's Etsy bill charges and payments. | | `cart_r` | Read the contents of a member’s cart. | | `cart_w` | Add and remove listings from a member's cart. | | `email_r` | Read a user profile | | `favorites_r` | View a member's favorite listings and users. | | `favorites_w` | Add to and remove from a member's favorite listings and users. | | `feedback_r` | View all details of a member's feedback (including purchase history.) | | `listings_d` | Delete a member's listings. | | `listings_r` | Read a member's inactive and expired (i.e., non-public) listings. | | `listings_w` | Create and edit a member's listings. | | `profile_r` | Read a member's private profile information. | | `profile_w` | Update a member's private profile information. | | `recommend_r` | View a member's recommended listings. | | `recommend_w` | Remove a member's recommended listings. | | `shops_r` | See a member's shop description, messages and sections, even if not (yet) public. | | `shops_w` | Update a member's shop description, messages and sections. | | `transactions_r` | Read a member's purchase and sales data. This applies to buyers as well as sellers. | | `transactions_w` | Update a member's sales data. | Scopes are associated with every access token, and any change in scope requires the user to re-authorize the application; to change scopes, you must go through the authorization code grant flow again. Conversely, users are generally less likely to authorize an application that makes a request for more scopes than it requires. As such, you should carefully tailor scope requests to your application. To request multiple scopes, add them in a space-separated list. For example, to request the scopes to see a user’s shipping addresses and email address, add the `email_r%20address_r` strings for the scope parameter in the request for an authentication code. Proof Key for Code Exchange (PKCE)[#](https://developers.etsy.com/documentation/essentials/authentication#proof-key-for-code-exchange-pkce "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------- A Proof Key for Code Exchange (PKCE) is the implementation of an OAuth2 extension standardized in RFC 7636 that guarantees that an authorization code is valid for only one application and cannot be intercepted by the user or an attacker. The Etsy Open API requires a PKCE on every authorization flow request. A PKCE works by using a code **verifier** , which must be a high-entropy random string consisting of between 43 and 128 characters from the range `[A-Za-z0-9._~-]` (i.e. unreserved URI characters). You can generate an appropriate verifier using a cryptographically secure source of randomness and encode 32 bytes of random data into url-safe base 64. Store this value in association with a particular authorization code request. Then construct a code **challenge** by taking the URL-safe base64-encoded output of the SHA256 hash of the code verifier, and use it in the authorization code request to `https://www.etsy.com/oauth/connect`. You must provide the verifier in the request for an access token from the Etsy API server, which proves that you are the source of the original authorization request. For an example of how to generate a code verifier and matching challenge, see [Appendix B of RFC 7636](https://tools.ietf.org/html/rfc7636#appendix-B) . Requesting a Refresh OAuth Token[#](https://developers.etsy.com/documentation/essentials/authentication#requesting-a-refresh-oauth-token "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------- Etsy's Open API supports OAuth 2.0 [Refresh Grants](https://datatracker.ietf.org/doc/html/rfc6749#section-1.5) to generate OAuth tokens after the seller grants a user an initial Authorization Code grant token. Refresh tokens do not require sellers to re-approve access and have the same scope as the token granted by the initial Authorization Code grant token. You cannot change the scope of a refresh token from the scope established in the initial Authentication Grant token. To obtain a refresh token, make a POST request to `https://api.etsy.com/v3/public/oauth/token` with the following parameters in the request body in `application/x-www-form-urlencoded` format: | Parameter Name | Description | | --- | --- | | `grant_type` | Must be the value `refresh_token` | | `client_id` | An Etsy App API Key _keystring_ for the app. | | `refresh_token` | The _refresh token_ string sent with a prior Authorization Code Grant or Refresh Grant. | For example, to request a refresh token for an Etsy app with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff`, initiate a POST request: https://api.etsy.com/v3/public/oauth/token? grant\_type=refresh\_token &client\_id=1aa2bb33c44d55eeeeee6fff &refresh\_token=12345678.JNGIJtvLmwfDMhlYoOJl8aLR1BWottyHC6yhNcET-eC7RogSR5e1GTIXGrgrelWZalvh3YvvyLfKYYqvymd-u37Sjtx Copy where: * `grant_type=refresh_code` is required to request an OAuth token in a refresh grant context. * `client_id=1aa2bb33c44d55eeeeee6fff` is an API Key _keystring_ for the app. * `refresh_token=12345678.JNGIJtvLmwfDMhlYoOJl8aLR1BWottyHC6yhNcET-eC7RogSR5e1GTIXGrgrelWZalvh3YvvyLfKYYqvymd-u37Sjtx` is the refresh code sent from Etsy.com after granting a prior authorization grant token or refresh grant token. The Etsy Open API responds to an authentic request for an OAuth token with the following information in JSON format: { "access\_token": "12345678.O1zLuwveeKjpIqCQFfmR-PaMMpBmagH6DljRAkK9qt05OtRKiANJOyZlMx3WQ\_o2FdComQGuoiAWy3dxyGI4Ke\_76PR", "token\_type": "Bearer", "expires\_in": 3600, "refresh\_token": "12345678.JNGIJtvLmwfDMhlYoOJl8aLR1BWottyHC6yhNcET-eC7RogSR5e1GTIXGrgrelWZalvh3YvvyLfKYYqvymd-u37Sjtx" } Copy where: * `access_token` is the OAuth refresh code with a user id numeric prefix (`12345678` in the example above), which is the internal `user_id` of the Etsy.com user who grants the application access. * `token_type` is always `Bearer` which indicates that the OAuth token is a bearer token. * `expires_in` is the valid duration of the OAuth token in seconds from the moment it is granted; 3600 seconds is 1 hour. * `refresh_token` is the OAuth code to request another refresh token with a user id numeric prefix (`12345678` in the example). Use this for a refresh grant access request for a fresh OAuth token without requesting access from the user/seller an additional time. APIv2 Endpoints and OAuth2 Tokens[#](https://developers.etsy.com/documentation/essentials/authentication#apiv2-endpoints-and-oauth2-tokens "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------- Requests to v2 endpoints cannot use tokens generated through the OAuth 2.0 flow described above. Requests to v3 endpoints must use OAuth 2.0 tokens. See [Exchange OAuth 1.0 Token for OAuth 2.0 Token](https://developers.etsy.com/documentation/essentials/authentication/#exchange-oauth-10-token-for-oauth-20-token) to upgrade existing tokens. ### Scopes changed for OAuth 1.0 in the V3 Open API[#](https://developers.etsy.com/documentation/essentials/authentication#scopes-changed-for-oauth-10-in-the-v3-open-api "Direct link to heading") The V3 Open API supports most of the same scopes for OAuth 1.0 that were supported in V2. However, the following scopes are different from the scopes supported for V2, so you should update them if you use them: 1. Several combined read and write scopes from v2 are split into separate read scopes and write scopes in v3 | V2 scope | V3 scopes | Description | Affected Resources | | --- | --- | --- | --- | | `favorites_rw` | `favorites_r` | View a member's favorite listings and users. | FavoriteListing and FavoriteUser | | | `favorites_w` | Add to and remove from a member's favorite listings and users. | FavoriteListing and FavoriteUser | | `shops_rw` | `shops_r` | View a member's shop description, messages and ections. | Shop and ShopSection | | | `shops_w` | Update a member's shop description, messages and sections. | Shop and ShopSection | | `cart_rw` | `cart_r` | View listings from a member's shopping cart. | Cart and CartListing | | | `cart_w` | Add and remove listings from a member's shopping cart. | Cart and CartListing | | `recommend_rw` | `recommend_r` | View a member's recommended listings. | Listing | | | `recommend_w` | Accept and reject a member's recommended listings. | Listing | 2. `collection_rw`, `page_collection_rw`, and `activity_r` are not implemented because no active end points use them. 3. `treasury_r` and `treasury_w` are not valid because we discontinued the treasury feature. ### Exchange OAuth 1.0 Token for OAuth 2.0 Token[#](https://developers.etsy.com/documentation/essentials/authentication#exchange-oauth-10-token-for-oauth-20-token "Direct link to heading") Etsy now supports OAuth 2.0 and existing Open API v3 applications that use OAuth 1.0 must either exchange their OAuth 1.0 access tokens for OAuth 2.0 access tokens or generate OAuth 2.0 access tokens using the OAuth 2.0 Authentication Code flow to use Open API v3 endpoints. To exchange an OAuth 1.0 token for a new OAuth 2.0 token, make a POST request to `https://api.etsy.com/v3/public/oauth/token` with the following parameters in the request body in `application/x-www-form-urlencoded` format: | Parameter Name | Description | | --- | --- | | `grant_type` | Must be the value `token_exchange` | | `client_id` | An Etsy App API Key _keystring_ for the app. | | `legacy_token` | The _legacy token_ is the current OAuth 1.0 token used by the application. | For example, to exchange an access for a new OAuth 2.0 access token on an Etsy app with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff` and legacy token of `eeb39b80e3f43a4671b00dbedaa74e`, initiate a POST request: https://api.etsy.com/v3/public/oauth/token? grant\_type=token\_exchange &client\_id=1aa2bb33c44d55eeeeee6fff &legacy\_token=eeb39b80e3f43a4671b00dbedaa74e Copy The Etsy Open API responds to an authentic token exchange request with the following information in JSON format: { "access\_token": "14099992.HZ3dHl\_DTh-mhPntSLRPg\_Q6hb2S9hsWsX8T-DxkEyzxYzFNFjhl7GsNhS8sps03RVDWlHttE8\_0Am9aA4dy9Xztwdz", "token\_type": "Bearer", "expires\_in": 3600, "refresh\_token": "14099992.nJME1eWEAMw0asH3PG\_mYilsD9neDny5x5WXF3FRIBXW\_xylVH0sILgbu2ER7TQRCmBdluHakZdffPF7qEtQ0kBlWb8" } Copy **Note:** OAuth 2.0 tokens generated from an OAuth 1.0 token exchange retain the scope(s) of the original OAuth 1.0 token. * [Requesting an OAuth Token](https://developers.etsy.com/documentation/essentials/authentication#requesting-an-oauth-token) * [Step 1: Request an Authorization Code](https://developers.etsy.com/documentation/essentials/authentication#step-1-request-an-authorization-code) * [Step 2: Grant Access](https://developers.etsy.com/documentation/essentials/authentication#step-2-grant-access) * [Step 3: Request an Access Token](https://developers.etsy.com/documentation/essentials/authentication#step-3-request-an-access-token) * [Redirect URIs](https://developers.etsy.com/documentation/essentials/authentication#redirect-uris) * [Scopes](https://developers.etsy.com/documentation/essentials/authentication#scopes) * [Proof Key for Code Exchange (PKCE)](https://developers.etsy.com/documentation/essentials/authentication#proof-key-for-code-exchange-pkce) * [Requesting a Refresh OAuth Token](https://developers.etsy.com/documentation/essentials/authentication#requesting-a-refresh-oauth-token) * [APIv2 Endpoints and OAuth2 Tokens](https://developers.etsy.com/documentation/essentials/authentication#apiv2-endpoints-and-oauth2-tokens) * [Scopes changed for OAuth 1.0 in the V3 Open API](https://developers.etsy.com/documentation/essentials/authentication#scopes-changed-for-oauth-10-in-the-v3-open-api) * [Exchange OAuth 1.0 Token for OAuth 2.0 Token](https://developers.etsy.com/documentation/essentials/authentication#exchange-oauth-10-token-for-oauth-20-token) --- # Webhooks | Etsy Open API v3 Webhooks provide real-time notifications to approved Etsy applications when defined events occur. Rather than polling the API for changes, your app can subscribe to webhook events and receive updates as soon as they happen. You can see our available events [here](https://developers.etsy.com/documentation/essentials/webhooks#available-events) . Watch our GitHub Announcements for updates: [https://github.com/etsy/open-api/discussions/categories/announcements](https://github.com/etsy/open-api/discussions/categories/announcements) Webhook functionality is available for both **commercial** and **personal** applications! Webhook Concepts[#](https://developers.etsy.com/documentation/essentials/webhooks#webhook-concepts "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------- * **Endpoints** – A destination URL where Etsy delivers webhook messages for the events you subscribe to. * **Events** – Specific actions or changes that trigger a webhook. * **Messages/Deliveries** – Each time an event occurs, Etsy sends a message (payload) to the configured endpoint. * **Signing Secrets** – Used to validate the authenticity of incoming webhook requests. * **Retries** – Etsy automatically retries delivery when your endpoint fails to acknowledge receipt. Managing Webhooks[#](https://developers.etsy.com/documentation/essentials/webhooks#managing-webhooks "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------- ### Prerequisites[#](https://developers.etsy.com/documentation/essentials/webhooks#prerequisites "Direct link to heading") * You must have a valid OAuth 2.0 access token with the appropriate scopes (depending on your app’s function). * For webhook delivery, provide a publicly accessible callback URL configured to receive POST requests from Etsy. Available Events[#](https://developers.etsy.com/documentation/essentials/webhooks#available-events "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------- We currently support the following events: * `order.paid` – delivered immediately when an order receives payment. * `order.canceled` - delivered immediately when a seller inititaites a cancelation. Stay tuned to our [announcements](https://github.com/etsy/open-api/discussions/categories/announcements) for more events coming soon! Payload Structure[#](https://developers.etsy.com/documentation/essentials/webhooks#payload-structure "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------- Each webhook event is delivered as a JSON payload. Although payloads differ by event type, all webhook deliveries share the following common fields: * `event_type` – The name of the event that triggered the webhook (e.g., `order.paid`). * `event_id` – A unique identifier for this event instance. * `created_at` – Timestamp of when the event occurred. * `data` – Object containing the event-specific fields. Here’s an example of how `order.paid` event's `data` attribute would look like: { "event\_type": "order.paid", "resource\_url": "https://api.etsy.com/v3/application/shops/{YOUR\_SHOP\_ID}/receipts/{RECEIPT\_ID} ", "shop\_id": {YOUR\_SHOP\_ID} } Copy Verifying Webhook Signatures[#](https://developers.etsy.com/documentation/essentials/webhooks#verifying-webhook-signatures "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------------------------------- ### Why signature verification matters[#](https://developers.etsy.com/documentation/essentials/webhooks#why-signature-verification-matters "Direct link to heading") Without verifying signatures, malicious actors could send forged webhook requests to your endpoint and trigger unintended behaviour. Proper verification ensures that: * The request originated from Etsy * The payload has not been tampered with * You avoid processing duplicate or replayed messages ### What do you need[#](https://developers.etsy.com/documentation/essentials/webhooks#what-do-you-need "Direct link to heading") * A signing secret, which you can retrieve from your Webhook Portal ![img](https://developers.etsy.com/assets/images/signing_secret-4c35a363be251ea116371faec17fab7e.png) * You can find this in the details of your webhook event. * Three special headers + raw body from each request, to be used to validate the payload ### What you will see on incoming requests[#](https://developers.etsy.com/documentation/essentials/webhooks#what-you-will-see-on-incoming-requests "Direct link to heading") Each webhook request will be an HTTP POST to your endpoint that includes: * Raw request body (JSON) * Headers: * `webhook-id` – unique ID of the webhook call (even on retries) * `webhook-timestamp` – unix timestamp (seconds) when the event was emitted * `webhook-signature` – this is what will be used to compare with your signing secret ### How to compute and verify the signature[#](https://developers.etsy.com/documentation/essentials/webhooks#how-to-compute-and-verify-the-signature "Direct link to heading") 1. Build the "signed content” string such as: signed\_content = webhook-id + "." + webhook-timestamp + "." + raw\_body Copy In this example, `raw_body` is the exact bytes/string of the HTTP body **before** any JSON parsing. 2. Derive the secret key. * Take your secret from the dashboard ![img](https://developers.etsy.com/assets/images/signing_secret-4c35a363be251ea116371faec17fab7e.png) * Remove the `whsec_` prefix. * Base64-decode the remaining part of the bytes. 3. Compute the expected signature: * HMAC-SHA256 over `signed_content` (step 1) using the decoded secret key (step 2). * Base64-encode the result Here’s a pseudo code example of what this would look like: secret\_bytes = base64\_decode(secret.split("\_")\[1\]) expected\_sig = base64\_encode(HMAC\_SHA256(secret\_bytes, signed\_content)) Copy 4. Compare against the `webhook-signature` header. * Check if any of the entries (if more than one) equals your `expected_sig` (step 3). * If there’s **no match**, **reject** the webhook. * If it’s a match, you may proceed with JSON parsing of the raw body or what your integration requires to interpret this data. ### Preventing Replay Attacks[#](https://developers.etsy.com/documentation/essentials/webhooks#preventing-replay-attacks "Direct link to heading") Even if the signature matches, an attacker could replay an old, captured request. To mitigate that: 1. Read webhook-timestamp 2. Compare it to your current server time 3. Reject if it’s older/newer than your allowed margin. In your code, it should roughly look like this: now = current\_unix\_time() if abs(now - webhook-timestamp) > 300: reject("Stale timestamp") Copy Managing Webhook Events[#](https://developers.etsy.com/documentation/essentials/webhooks#managing-webhook-events "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------- From the Webhooks section of your application dashboard, you can: * View a list of your active webhook subscriptions. * Inspect details of each subscription, including event type, callback URL, secret (masked), creation date, and delivery history. * Delete or disable subscriptions you no longer need, which will immediately stop event deliveries. When you subscribe to an event, Etsy will send a POST request to your callback URL when the event is triggered. ### Access the Webhooks Portal[#](https://developers.etsy.com/documentation/essentials/webhooks#access-the-webhooks-portal "Direct link to heading") 1. Navigate to **Manage your apps** in the Developer Portal. ![img](https://developers.etsy.com/assets/images/manage_your_app_step_1-44afde2a232735de449f79ce710bfe6a.png) 2. Click the dropdown menu for your **commercial** app and select **Go to Webhook portal**. ![img](https://developers.etsy.com/assets/images/dropdown_menu-d1124d8094ced477635869a00790cf3d.png) ![img](https://developers.etsy.com/assets/images/dropdown_menu_show-e0962fb2e37550facf49c7a7dec3d970.png) You will see your portal. ![img](https://developers.etsy.com/assets/images/portal_view-9296ab48b0ea1401f24a84f4ee9dbedf.png) ### Configure a Subscription[#](https://developers.etsy.com/documentation/essentials/webhooks#configure-a-subscription "Direct link to heading") Assuming you followed the steps from [Access the Webhooks Portal](https://developers.etsy.com/documentation/essentials/webhooks#access-the-webhooks-portal) , to configure a subscription: 1. Choose **+Add Endpoint**. ![img](https://developers.etsy.com/assets/images/add_endpoint-e71abe6d7c4af498053b59625e7e649e.png) 2. Enter your **callback URL** and the event you wish to subscribe to. ![img](https://developers.etsy.com/assets/images/create_form-e8dd20c373813bae831976a7efee9830.png) 3. Click **Create**. Once saved, your callback URL will receive webhook payloads when the event occurs. ##### Important Because webhooks deliver asynchronous notifications, ensure your server can handle incoming POST requests and validate signatures. ### How to Unsubscribe (Delete or Disable a Webhook)[#](https://developers.etsy.com/documentation/essentials/webhooks#how-to-unsubscribe-delete-or-disable-a-webhook "Direct link to heading") ##### warning Disabled endpoints remain visible in your dashboard and can be re-enabled at any time. _Deleted endpoints cannot be recovered._ #### Delete a Webhook[#](https://developers.etsy.com/documentation/essentials/webhooks#delete-a-webhook "Direct link to heading") Assuming you followed the steps from [Access the Webhooks Portal](https://developers.etsy.com/documentation/essentials/webhooks#access-the-webhooks-portal) ,to fully delete a webhook subscription: 1. Select the subscription you wish to remove. 2. Click the 3 dots on the upper right corner and select **Delete**. ![img](https://developers.etsy.com/assets/images/select_dropdown-67006efeabdeab843a71e01886dec35c.png) ![img](https://developers.etsy.com/assets/images/delete_select-52642e3c42bd4547ec72cb06fb2555b2.png) 3. Confirm deletion. ![img](https://developers.etsy.com/assets/images/confirm_delete-05d139ee919b98a04b7db1590295b33e.png) After deletion, no further events will be delivered for that subscription. ##### caution Deleting an endpoint will permanently delete all of its data. #### Disable a Webhook[#](https://developers.etsy.com/documentation/essentials/webhooks#disable-a-webhook "Direct link to heading") Assuming you followed the steps from [Access the Webhooks Portal](https://developers.etsy.com/documentation/essentials/webhooks#access-the-webhooks-portal) , to disable a webhook subscription: 1. Select the subscription you wish to disable. 2. Click the 3 dots on the upper right corner and select **Disable Endpoint**. ![img](https://developers.etsy.com/assets/images/select_dropdown-67006efeabdeab843a71e01886dec35c.png) ![img](https://developers.etsy.com/assets/images/disable_select-f87acd8b9265456a431ef4fcff23e3cf.png) To enable the event again, do the same process but click **Enable Endpoint**. ![img](https://developers.etsy.com/assets/images/enable_endpoint-4b5cf0487c6d2166a4e261098f2fe8b6.png) Monitoring Webhook Activity[#](https://developers.etsy.com/documentation/essentials/webhooks#monitoring-webhook-activity "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------- Each subscription includes tools and data to help monitor webhook performance and flow. These insights allow developers to troubleshoot issues and understand how the webhook behaves over time. ### General Information[#](https://developers.etsy.com/documentation/essentials/webhooks#general-information "Direct link to heading") The detail view displays metadata about the subscription, including the date and time it was created. This helps track when the webhook was first configured. ![img](https://developers.etsy.com/assets/images/webhook_detail-ac7ff9178ed5a17c3100f4a75fa9cd28.png) ### Delivery Stats[#](https://developers.etsy.com/documentation/essentials/webhooks#delivery-stats "Direct link to heading") The monitoring section provides an overview of delivery performance. This may include the number of events delivered, recent activity, and overall delivery patterns. ![img](https://developers.etsy.com/assets/images/stats-9c9a98a641913d7aa4219e1ad04edf38.png) ### Message Attempts[#](https://developers.etsy.com/documentation/essentials/webhooks#message-attempts "Direct link to heading") For each attempted delivery, you can view whether a message was successfully delivered or if retries occurred. This supports debugging of callback endpoints and helps identify transient or persistent delivery issues. ![img](https://developers.etsy.com/assets/images/message_attempts-6f6f0eb7ca2e74cfd720c4dde7418e58.png) ### Payload Details[#](https://developers.etsy.com/documentation/essentials/webhooks#payload-details "Direct link to heading") Recent event payloads appear in the activity log. Developers can inspect these payloads to validate data fields, ensure that their system is parsing them correctly, or verify that events are arriving in the expected format. By clicking one of the message attempts, you can see the message’s details. ![img](https://developers.etsy.com/assets/images/payload_details-2695c3e53277a800cf13fe1e7ae0ad01.png) ### Endpoint Status[#](https://developers.etsy.com/documentation/essentials/webhooks#endpoint-status "Direct link to heading") The detail view displays whether the endpoint is active or disabled. Disabled endpoints do not receive events until re-enabled. ![img](https://developers.etsy.com/assets/images/endpoint_status-40a36c54511edae3ec69b0fc113a9e0e.png) Delivery Retries[#](https://developers.etsy.com/documentation/essentials/webhooks#delivery-retries "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------- We attempt to deliver each webhook message based on a retry schedule with exponential backoff. ### The Schedule[#](https://developers.etsy.com/documentation/essentials/webhooks#the-schedule "Direct link to heading") Each message is attempted based on the following schedule, where each period is started following the failure of the preceding attempt: * Immediately * 5 seconds * 5 minutes * 30 minutes * 2 hours * 5 hours * 10 hours * 10 hours (in addition to the previous) If an endpoint is removed or disabled delivery attempts to the endpoint will be disabled as well. For example, an attempt that fails three times before eventually succeeding will be delivered roughly 35 minutes and 5 seconds following the first attempt. ### Manual retries[#](https://developers.etsy.com/documentation/essentials/webhooks#manual-retries "Direct link to heading") You can also use the application portal to manually retry each message at any time, or automatically retry ("Recover") all failed messages starting from a given date. ![img](https://developers.etsy.com/assets/images/recover_replay-f4a77e2c3f9637ce3f86ebc463fb04a1.png) Testing Webhooks[#](https://developers.etsy.com/documentation/essentials/webhooks#testing-webhooks "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------- The Webhook Portal includes tools for sending test events to your endpoint. Use this to validate: * Endpoint availability * Signature verification * Event-processing logic * Error-handling behavior You can access the testing tab of your webhook event by clicking the event to access its details. ![img](https://developers.etsy.com/assets/images/access_details-28b0aab552bf9091be7aa9748e85ea2a.png) And then selecting the **Testing** tab. ![img](https://developers.etsy.com/assets/images/testing_tab-b88920ca304fcca418449a66fdd95e5d.png) * [Webhook Concepts](https://developers.etsy.com/documentation/essentials/webhooks#webhook-concepts) * [Managing Webhooks](https://developers.etsy.com/documentation/essentials/webhooks#managing-webhooks) * [Prerequisites](https://developers.etsy.com/documentation/essentials/webhooks#prerequisites) * [Available Events](https://developers.etsy.com/documentation/essentials/webhooks#available-events) * [Payload Structure](https://developers.etsy.com/documentation/essentials/webhooks#payload-structure) * [Verifying Webhook Signatures](https://developers.etsy.com/documentation/essentials/webhooks#verifying-webhook-signatures) * [Why signature verification matters](https://developers.etsy.com/documentation/essentials/webhooks#why-signature-verification-matters) * [What do you need](https://developers.etsy.com/documentation/essentials/webhooks#what-do-you-need) * [What you will see on incoming requests](https://developers.etsy.com/documentation/essentials/webhooks#what-you-will-see-on-incoming-requests) * [How to compute and verify the signature](https://developers.etsy.com/documentation/essentials/webhooks#how-to-compute-and-verify-the-signature) * [Preventing Replay Attacks](https://developers.etsy.com/documentation/essentials/webhooks#preventing-replay-attacks) * [Managing Webhook Events](https://developers.etsy.com/documentation/essentials/webhooks#managing-webhook-events) * [Access the Webhooks Portal](https://developers.etsy.com/documentation/essentials/webhooks#access-the-webhooks-portal) * [Configure a Subscription](https://developers.etsy.com/documentation/essentials/webhooks#configure-a-subscription) * [How to Unsubscribe (Delete or Disable a Webhook)](https://developers.etsy.com/documentation/essentials/webhooks#how-to-unsubscribe-delete-or-disable-a-webhook) * [Monitoring Webhook Activity](https://developers.etsy.com/documentation/essentials/webhooks#monitoring-webhook-activity) * [General Information](https://developers.etsy.com/documentation/essentials/webhooks#general-information) * [Delivery Stats](https://developers.etsy.com/documentation/essentials/webhooks#delivery-stats) * [Message Attempts](https://developers.etsy.com/documentation/essentials/webhooks#message-attempts) * [Payload Details](https://developers.etsy.com/documentation/essentials/webhooks#payload-details) * [Endpoint Status](https://developers.etsy.com/documentation/essentials/webhooks#endpoint-status) * [Delivery Retries](https://developers.etsy.com/documentation/essentials/webhooks#delivery-retries) * [The Schedule](https://developers.etsy.com/documentation/essentials/webhooks#the-schedule) * [Manual retries](https://developers.etsy.com/documentation/essentials/webhooks#manual-retries) * [Testing Webhooks](https://developers.etsy.com/documentation/essentials/webhooks#testing-webhooks) --- # Fulfillment Tutorial | Etsy Open API v3 ##### important These tutorials are subject to change as endpoints change during our feedback period development. We welcome your feedback! If you find an error or have a suggestion, please post it in the [Open API GitHub Repository](https://github.com/etsy/open-api) . Fulfillment covers all shipping and handling activities required to ship and return customer orders. Additionally, when your app submits tracking information for shipping, Etsy triggers the final calculations for the purchase transaction, including Value Added Tax (VAT), tax, and shipping costs, resulting in complete receipts. _Throughout this tutorial, the instructions reference REST resources, endpoints, parameters, and response fields, which we cover in detail in [Request Standards](https://developers.etsy.com/documentation/essentials/requests) and [URL Syntax](https://developers.etsy.com/documentation/essentials/urlsyntax) ._ ### `Authorization` and `x-api-key` header parameters[#](https://developers.etsy.com/documentation/tutorials/fulfillment#authorization-and-x-api-key-header-parameters "Direct link to heading") The endpoints in this tutorial require an OAuth token in the header with `transactions_r` and `transactions_w` scope. See the [Authentication topic](https://developers.etsy.com/documentation/essentials/authentication) for instructions on how to generate an OAuth token with these scopes. In addition, all Open API V3 requests require the `x-api-key:` header with your shop's Etsy App API Key _keystring_ and _shared secret_, separated by a colon (`:`), which you can find in [Your Apps](https://www.etsy.com/developers/your-apps) . Fulfilling Digital Orders[#](https://developers.etsy.com/documentation/tutorials/fulfillment#fulfilling-digital-orders "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------- A seller typically does not need to do anything to fulfill orders for digital products after creating the listing and uploading files for buyers to buy. Buyers can download files from their purchase history forever once purchased, even if the seller stops offering that digital product for sale. However, there are a few important details a seller should be aware of following the fulfillment of a digital order: 1. Files purchased by buyers in the past aren't automatically updated when you update the listing with newer version of the file. 2. You must include any tax amounts applicable to the purchase in the purchase price, as Etsy doesn't add tax automatically to digital products except for calculated Value Added Tax (VAT) amounts. See [How VAT Works on Digital Items](https://help.etsy.com/hc/en-us/articles/115015587567-How-VAT-Works-on-Digital-Items?segment=selling) for more information on calculated VAT for digital products. Fulfilling Physical Product Orders[#](https://developers.etsy.com/documentation/tutorials/fulfillment#fulfilling-physical-product-orders "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------- You fulfill physical product orders by shipping them and using the [`createReceiptShipment`](https://developers.etsy.com/documentation/reference/#operation/createReceiptShipment) to add the carrier and tracking information to your shop and customers. To get a list of shipping carriers for a shop, use [getShippingCarriers](https://developers.etsy.com/documentation/reference/#operation/getShippingCarriers) or see [Tracking updates for shipping carriers](https://developers.etsy.com/documentation/tutorials/fulfillment#tracking-updates-for-shipping-carriers) below. Etsy posts the final transaction total immidately after a seller posts shipping details, so the response from createReceiptShipment includes calculated taxes, discounts, gift wrap prices, etc. **Additionally, successful createReceiptShipment requests send a notification email to the buyer.** Sellers enter shipping costs as part of a shipping profile using [Shipping Profile endpoints](https://developers.etsy.com/documentation/reference#tag/Shop-ShippingProfile) . See the [listings tutorial](https://developers.etsy.com/documentation/tutorials/listings) for instructions on adding a shipping profile to a listing. Sellers can purchase shipping through Etsy, but the Open API v3 does not include an endpoint to order shipping, so the seller must enter costs into shipping profiles, purchase shipping, and print shipping labels themselves. See [How to Purchase Etsy Shipping Labels](https://help.etsy.com/hc/en-us/articles/360001967188-How-to-Purchase-Etsy-Shipping-Labels?segment=selling) for all carriers Etsy supports directly in the seller tools. The following procedure adds shipping tracking information to a receipt: 1. Form a valid URL for [`createReceiptShipment`](https://developers.etsy.com/documentation/reference/#operation/createReceiptShipment) , which must include a `shop_id` for the shop and the `receipt_id` for the purchase. For example, if your shop\_id is 12345678 and your receipt\_id is 090898651, the createShopSection URL is: https://api.etsy.com/v3/application/shops/12345678/receipts/090898651/tracking Copy 2. Build the createReceiptShipment request body, which must include `tracking_code` string provided by the carrier and `carrier_name` string to identify the carrier. Etsy supports tracking updates for many shipping carriers as determined by the `carrier_name` parameter. See [Tracking updates for shipping carriers](https://developers.etsy.com/documentation/tutorials/fulfillment#tracking-updates-for-shipping-carriers) below. 3. Execute a createReceiptShipment POST request with a `transactions_w` scope OAuth token and `x-api-key`. For example, a createReceiptShipment request to create the "Spiral Carpet" section might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "2lk6cu87j83a15eqnfmf7ysk:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var urlencoded \= new URLSearchParams(); urlencoded.append("tracking\_code", "KB6NANRE9noji32oOU34h"); urlencoded.append("carrier\_name", "fedex"); var requestOptions \= { method: 'POST', headers: headers, body: urlencoded, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/receipts/090898651/tracking", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678/receipts/090898651/tracking', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'POST', CURLOPT\_POSTFIELDS \=> 'tracking\_code=KB6NANRE9noji32oOU34h&carrier\_name=fedex' CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 2lk6cu87j83a15eqnfmf7ysk:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy ### Tracking updates for shipping carriers[#](https://developers.etsy.com/documentation/tutorials/fulfillment#tracking-updates-for-shipping-carriers "Direct link to heading") Etsy supports tracking updates for several carriers, determined by the `carrier_name` submitted with a createShippingReceipt request. Tracking updates provide a tracking link in the shipping notification email and displays tracking updates for the shipment on Etsy. The table below lists known carriers, the `carrier_name` parameter values, and whether Etsy supports tracking updates for that organization. | Carrier | `carrier_name` | Tracking Updates | | --- | --- | --- | | 4PX Worldwide Express | 4px | Yes | | A1Post | a1post | Yes | | ABF Freight | abf | Yes | | ACS Courier | acscourier | Yes | | AeroFlash | aeroflash | Yes | | Afghan Post | afghan-post | No | | Amazon Logistics UK | amazon-uk-api | Yes | | Amazon Logistics US | amazon | Yes | | An Post | an-post | Yes | | Anguilla Postal Service | anguilla-post | No | | APC Postal Logistics | apc | Yes | | Aramex | aramex | Yes | | Asendia UK | asendia-uk | Yes | | Asendia USA | asendia-usa | Yes | | Australia Post | australia-post | Yes | | Austrian Post | austrian-post | Yes | | Austrian Post Registered | austrian-post-registered | Yes | | Bahrain Post | bahrain-post | No | | Bangladesh Post Office | bangladesh-post | No | | Belgium Post Domestic | bpost | Yes | | Belgium Post International | bpost-international | Yes | | Belposhta | belpost | Yes | | BH Posta | bh-posta | No | | Blue Dart | bluedart | Yes | | BotswanaPost | botswanapost | No | | Brunei Postal Services | brunei-post | No | | Bulgarian Posts | bgpost | Yes | | Cambodia Post | cambodia-post | Yes | | Canada Post | canada-post | Yes | | Canpar Courier | canpar | Yes | | Ceska Posta | ceska-posta | Yes | | China EMS | china-ems | Yes | | China Post | china-post | Yes | | Chit Chats | chitchats | Yes | | Chronopost France | chronopost-france | Yes | | Chronopost Portugal | chronopost-portugal | Yes | | Chunghwa Post | taiwan-post | Yes | | City Link | city-link | Yes | | Colissimo | colissimo | Yes | | Collect+ | collectplus | Yes | | Correios de Brasil | brazil-correios | Yes | | Correios de Macau | correios-macau | No | | Correios de Portugal (CTT) | portugal-ctt | Yes | | Correo Argentino Domestic | correo-argentino | Yes | | Correo Argentino International | correo-argentino-intl | Yes | | Correo Uruguayo | correo-uruguayo | No | | Correos - Espana | spain-correos-es | Yes | | Correos Chile | correos-chile | Yes | | Correos De Mexico | correos-de-mexico | Yes | | Correos de Costa Rica | correos-de-costa-rica | Yes | | Correos del Ecuador | correos-ecuador | No | | Courier Post | courierpost | Yes | | Couriers Please | couriers-please | Yes | | Cyprus Post | cyprus-post | Yes | | Deltec Courier | deltec-courier | Yes | | Deutsche Post | deutsch-post | Yes | | DHL Benelux | dhl-benelux | Yes | | DHL Express | dhl | Yes | | DHL Germany | dhl-germany | Yes | | DHL Global Mail | dhl-global-mail | Yes | | DHL Netherlands | dhl-nl | Yes | | DHL Parcel NL | dhlparcel-nl | Yes | | DHL Polska | dhl-poland | Yes | | DHL Spain Domestic | dhl-es | Yes | | DHL eCommerce | dhl-global-mail-asia | Yes | | Direct Link | directlink | Yes | | DPD | dpd | Yes | | DPD Germany | dpd-de | Yes | | DPD Polska | dpd-poland | Yes | | DPD UK | dpd-uk | Yes | | DTDC India | dtdc | Yes | | EC-Firstclass | ec-firstclass | Yes | | Egypt Post | egypt-post | No | | El Correo | el-correo | No | | Elta Courier | elta-courier | Yes | | Empost | emirates-post | Yes | | Empresa de Correos de Bolivia | correos-bolivia | No | | Estafeta | estafeta | Yes | | Estes | estes | Yes | | Estonian Post | estonian-post | No | | Ethiopian Postal Service | ethiopian-post | No | | Evergreen | evergreen | No | | Fastway Australia | fastway-au | Yes | | Fastway Couriers | fastway-ireland | Yes | | Fastway New Zealand | fastway-nz | Yes | | Fastways Couriers South Africa | fastway-za | Yes | | FedEx | fedex | Yes | | Fedex UK (Domestic) | fedex-uk | Yes | | First Flight Couriers | first-flight | Yes | | Flash Courier | flash-courier | Yes | | Freightquote by C. H. Robinson | freightquote | Yes | | GATI-KWE | gati-kwe | Yes | | Ghana Post | ghana-post | No | | Globegistics | globegistics | Yes | | GLS | gls | Yes | | Greyhound | greyhound | Yes | | Guernsey Post | guernsey-post | No | | Hay Post | hay-post | No | | Hellenic Post | hellenic-post | No | | Hermes | hermes-de | Yes | | Hermes Italy | hermes-it | Yes | | Hermes UK | hermes | Yes | | Hong Kong Post | hong-kong-post | Yes | | Hrvatska Posta | hrvatska-posta | Yes | | i-parcel | i-parcel | Yes | | India Post | india-post | Yes | | India Post International | india-post-int | Yes | | Interlink Express | interlink-express | Yes | | International Seur | international-seur | Yes | | Ipostel | ipostel | No | | Iran Post | iran-post | No | | Islandspostur | islandspostur | No | | Isle of Man Post Office | isle-of-man-post | No | | Israel Post | israel-post | Yes | | Israel Post Domestic | israel-post-domestic | Yes | | Jamaica Post | jamaica-post | No | | Japan Post | japan-post | Yes | | Jersey Post | jersey-post | No | | Jordan Post | jordan-post | No | | Kazpost | kazpost | No | | Korea Post | kpost | Yes | | Korea Post EMS | korea-post | Yes | | Kuehne + Nagel | kn | Yes | | La Poste | la-poste-colissimo | Yes | | La Poste Monaco | poste-monaco | No | | La Poste du Senegal | poste-senegal | No | | La Poste Tunisienne | poste-tunisienne | No | | Landmark Global | landmark-global | Yes | | LaserShip | lasership | Yes | | Latvijas Pasts | latvijas-pasts | No | | LibanPost | libanpost | No | | Lietuvos Pastas | lietuvos-pastas | Yes | | Magyar Posta | magyar-posta | Yes | | Makedonska Posta | makedonska-posta | No | | Malaysia Pos Daftar | malaysia-post-posdaftar | Yes | | Maldives Post | maldives-post | No | | MaltaPost | maltapost | No | | Mauritius Post | mauritius-post | No | | Mondial Relay | mondialrelay | Yes | | MRW | mrw-spain | Yes | | Multipack | mexico-multipack | Yes | | myHermes UK | myhermes-uk | Yes | | Nacex | nacex-spain | Yes | | New Zealand Post | new-zealand-post | Yes | | Nexive | tntpost-it | Yes | | Nieuwe Post Nederlandse Antillen (PNA) | nieuwe-post-nederlandse-antillen-pna | No | | Nigerian Postal Service | nipost | Yes | | Nova Poshta | nova-poshta | Yes | | OCA | oca-ar | Yes | | OPEK | opek | Yes | | Oman Post | oman-post | No | | OnTrac | ontrac | Yes | | OPT | opt | No | | OPT de Nouvelle-Caledonie | opt-nouvelle-caledonie | No | | Pakistan Post | pakistan-post | No | | Parcelforce Worldwide | parcel-force | Yes | | Poczta Polska | poczta-polska | Yes | | Pos Indonesia | pos-indonesia | Yes | | Pos Indonesia International | pos-indonesia-int | Yes | | Pos Malaysia | malaysia-post | Yes | | Post Aruba | post-aruba | No | | Post Fiji | post-fiji | No | | Post Luxembourg | post-luxembourg | No | | PostNL Domestic | postnl | Yes | | PostNL International | postnl-international | Yes | | PostNL International 3S | postnl-3s | Yes | | PostNord | danmark-post | Yes | | PostNord Logistics | postnord | Yes | | Posta | posta | No | | Posta Kenya | posta-kenya | No | | Posta Moldovei | posta-moldovei | No | | Posta Romana | posta-romana | Yes | | Posta Shqiptare | posta-shqiptare | No | | Posta Slovenije | posta-slovenije | No | | Posta Srbije | posta-srbije | No | | Posta Uganda | posta-uganda | No | | Poste Italiane | poste-italiane | Yes | | Poste Italiane Paccocelere | poste-italiane-paccocelere | Yes | | Poste Maroc | poste-maroc | No | | Posten AB | sweden-posten | Yes | | Posten Norge | posten-norge | Yes | | Posti | posti | Yes | | Postmates | postmates | Yes | | PTT Posta | ptt-posta | Yes | | Purolator | purolator | Yes | | Qatar Post | qatar-post | No | | Red Express | red-express | Yes | | Redpack | mexico-redpack | Yes | | Royal Mail | royal-mail | No | | RL Carriers | rl-carriers | Yes | | RPX Indonesia | rpx | Yes | | Russian Post | russian-post | Yes | | S.F International | sfb2c | Yes | | Safexpress | safexpress | Yes | | Sagawa | sagawa | Yes | | Saudi Post | saudi-post | Yes | | SDA Express Courier | italy-sda | Yes | | Selektvracht | selektvracht | Yes | | Senda Express | mexico-senda-express | Yes | | Sendle | sendle | Yes | | Serpost | serpost | No | | SEUR Espana (Domestico) | spanish-seur | Yes | | SEUR Portugal (Domestico) | portugal-seur | Yes | | SF Express | sf-express | Yes | | Singapore Post | singapore-post | Yes | | Singapore SpeedPost | singapore-speedpost | Yes | | Siodemka | siodemka | Yes | | Skynet Malaysia | skynet-malaysia | Yes | | SkyNet Wordwide Express | skynetworldwide | Yes | | Skynet Worldwide Express | skynetworldwide | Yes | | Slovenska posta | slovenska-posta | No | | South Africa Post Office | sapo | Yes | | Stallion Express | stallionexpress | Yes | | StarTrack | star-track | Yes | | Swiss Post | swiss-post | Yes | | TA-Q-BIN Hong Kong | taqbin-hk | Yes | | TA-Q-BIN Japan | taqbin-jp | Yes | | TA-Q-BIN Malaysia | taqbin-my | Yes | | TA-Q-BIN Singapore | taqbin-sg | Yes | | TGX | tgx | Yes | | Thailand Post | thailand-post | Yes | | TNT | tnt | Yes | | TNT Australia | tnt-au | Yes | | TNT France | tnt-fr | Yes | | TNT Italia | tnt-it | Yes | | TNT UK | tnt-uk | Yes | | Toll Global Express | toll-global-express | No | | Toll Priority | toll-priority | Yes | | TTPost | ttpost | No | | UK Mail | uk-mail | Yes | | UkrPoshta | ukrposhta | Yes | | UPS | ups | Yes | | UPS Freight | ups-freight | Yes | | uShip | uship | Yes | | USPS | usps | Yes | | Vanuatu Post | vanuatu-post | No | | Vietnam Post | vnpost | Yes | | Vietnam Post EMS | vnpost-ems | Yes | | Whistl | whistl | Yes | | Xend | xend | Yes | | Yakit | yakit | Yes | | Yanwen | yanwen | Yes | | Yemen Post | yemen-post | No | | Yodel | yodel | Yes | | Yodel International | yodel-international | Yes | | YRC Freight | yrc | Yes | | Zampost | zampost | No | | Zimpost | zimpost | No | ### Countries requiring postal codes[#](https://developers.etsy.com/documentation/tutorials/fulfillment#countries-requiring-postal-codes "Direct link to heading") Shipping profiles require valid postal code inputs for the following countries: | Country name | `iso_code` | | --- | --- | | Åland Islands | AX | | Albania | AL | | Algeria | DZ | | American Samoa | AS | | Andorra | AD | | Argentina | AR | | Armenia | AM | | Australia | AU | | Austria | AT | | Azerbaijan | AZ | | Bahrain | BH | | Bangladesh | BD | | Barbados | BB | | Belarus | BY | | Belgium | BE | | Bermuda | BM | | Bhutan | BT | | Bosnia and Herzegovina | BA | | Brazil | BR | | British Indian Ocean Territory | IO | | British Virgin Islands | VG | | Brunei | BN | | Bulgaria | BG | | Cambodia | KH | | Canada | CA | | Cape Verde | CV | | Cayman Islands | KY | | Chile | CL | | China | CN | | Christmas Island | CX | | Cocos (Keeling) Islands | CC | | Colombia | CO | | Costa Rica | CR | | Croatia | HR | | Cyprus | CY | | Czech Republic | CZ | | Denmark | DK | | Dominican Republic | DO | | Ecuador | EC | | Egypt | EG | | El Salvador | SV | | Estonia | EE | | Ethiopia | ET | | Falkland Islands (Malvinas) | FK | | Faroe Islands | FO | | Finland | FI | | France | FR | | French Guiana | GF | | French Polynesia | PF | | Georgia | GE | | Germany | DE | | Gibraltar | GI | | Greece | GR | | Greenland | GL | | Guadeloupe | GP | | Guam | GU | | Guatemala | GT | | Guernsey | GG | | Guinea | GN | | Guinea-Bissau | GW | | Haiti | HT | | Heard Island and McDonald Islands | HM | | Holy See (Vatican City State) | VA | | Honduras | HN | | Hungary | HU | | Iceland | IS | | India | IN | | Indonesia | ID | | Iran | IR | | Iraq | IQ | | Ireland | IE | | Isle of Man | IM | | Israel | IL | | Italy | IT | | Japan | JP | | Jersey | JE | | Jordan | JO | | Kazakhstan | KZ | | Kenya | KE | | Kuwait | KW | | Kyrgyzstan | KG | | Laos | LA | | Latvia | LV | | Lebanon | LB | | Lesotho | LS | | Liberia | LR | | Liechtenstein | LI | | Lithuania | LT | | Luxembourg | LU | | Macedonia | MK | | Madagascar | MG | | Malaysia | MY | | Maldives | MV | | Malta | MT | | Marshall Islands | MH | | Martinique | MQ | | Mauritius | MU | | Mayotte | YT | | Mexico | MX | | Micronesia, Federated States of | FM | | Moldova | MD | | Monaco | MC | | Mongolia | MN | | Montenegro | ME | | Morocco | MA | | Myanmar (Burma) | MM | | Nepal | NP | | New Caledonia | NC | | New Zealand | NZ | | Nicaragua | NI | | Niger | NE | | Nigeria | NG | | Norfolk Island | NF | | Northern Mariana Islands | MP | | Norway | NO | | Oman | OM | | Pakistan | PK | | Palau | PW | | Papua New Guinea | PG | | Paraguay | PY | | Peru | PE | | Philippines | PH | | Poland | PL | | Portugal | PT | | Puerto Rico | PR | | Reunion | RE | | Romania | RO | | Russia | RU | | Saint Barthélemy | BL | | Saint Helena | SH | | Saint Martin (French part) | MF | | Saint Pierre and Miquelon | PM | | Saint Vincent and the Grenadines | VC | | San Marino | SM | | Saudi Arabia | SA | | Senegal | SN | | Serbia | RS | | Singapore | SG | | Slovakia | SK | | Slovenia | SI | | Somalia | SO | | South Africa | ZA | | South Georgia and the South Sandwich Islands | GS | | South Korea | KR | | Spain | ES | | Sri Lanka | LK | | Svalbard and Jan Mayen | SJ | | Swaziland | SZ | | Sweden | SE | | Switzerland | CH | | Taiwan | TW | | Tajikistan | TJ | | Tanzania | TZ | | Thailand | TH | | The Netherlands | NL | | Tunisia | TN | | Turkey | TR | | Turkmenistan | TM | | Turks and Caicos Islands | TC | | Ukraine | UA | | United Kingdom | GB | | United States | US | | United States Minor Outlying Islands | UM | | Uruguay | UY | | U.S. Virgin Islands | VI | | Uzbekistan | UZ | | Venezuela | VE | | Vietnam | VN | | Wallis and Futuna | WF | | Western Sahara | EH | | Zambia | ZM | ### Country Holidays[#](https://developers.etsy.com/documentation/tutorials/fulfillment#country-holidays "Direct link to heading") Mapping of holidays that each country observes and it's corresponding ID. | United States | `holiday_id` | | --- | --- | | New Years Day | 1 | | Martin Luther King Jr. Day | 2 | | Presidents Day | 3 | | Memorial Day | 4 | | Juneteenth | 5 | | Independence Day | 6 | | Labor Day | 7 | | Columbus Day | 8 | | Veterans Day | 9 | | Thanksgiving Day | 10 | | Christmas Day | 11 | | Canada | `holiday_id` | | --- | --- | | Good Friday | 12 | | Easter | 13 | | Victoria Day | 14 | | Canada Day | 15 | | Truth and Reconciliation Day | 16 | | Rememberance Day | 17 | | Civic Holiday | 18 | | Boxing Day | 19 | | New Years Day | 20 | | Labour Day | 21 | | Thanksgiving Day | 22 | | Christmas Day | 23 | * [`Authorization` and `x-api-key` header parameters](https://developers.etsy.com/documentation/tutorials/fulfillment#authorization-and-x-api-key-header-parameters) * [Fulfilling Digital Orders](https://developers.etsy.com/documentation/tutorials/fulfillment#fulfilling-digital-orders) * [Fulfilling Physical Product Orders](https://developers.etsy.com/documentation/tutorials/fulfillment#fulfilling-physical-product-orders) * [Tracking updates for shipping carriers](https://developers.etsy.com/documentation/tutorials/fulfillment#tracking-updates-for-shipping-carriers) * [Countries requiring postal codes](https://developers.etsy.com/documentation/tutorials/fulfillment#countries-requiring-postal-codes) * [Country Holidays](https://developers.etsy.com/documentation/tutorials/fulfillment#country-holidays) --- # Rate Limits | Etsy Open API v3 Rate Limits and Authentication Types[#](https://developers.etsy.com/documentation/essentials/rate-limits#rate-limits-and-authentication-types "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The API enforces **application-based rate limits**, which consist of Queries Per Day (**QPD**) and Queries Per Second (**QPS**). These limits apply per API Key for public authentication and per OAuth access token for private authentication. **You can see your application's current rate limits in the [Developer Portal](https://www.etsy.com/developers/your-apps) .** * * * Daily Limit Mechanism (Sliding Window Structure)[#](https://developers.etsy.com/documentation/essentials/rate-limits#daily-limit-mechanism-sliding-window-structure "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The Queries Per Day (**QPD**) limit does not operate on a fixed 24-hour cycle (e.g., midnight-to-midnight). Instead, we employ a progressive **Sliding Window Rate Limiting Algorithm** to maximize your API usage. This mechanism calculates your usage based on the requests made over the **last rolling 24-hour period**. ### How the Sliding Window Works[#](https://developers.etsy.com/documentation/essentials/rate-limits#how-the-sliding-window-works "Direct link to heading") 1. **Buckets:** The 24-hour period is divided into a number of smaller, fixed time intervals called **buckets**. Your requests are recorded within these specific buckets. 2. **Calculation:** Your application's total usage is the sum of requests recorded in all buckets that fall within the current rolling 24-hour window. 3. **Sliding:** As time passes, the oldest bucket exits the 24-hour window, and a new, empty bucket enters. The quota consumed by the requests in the exiting bucket is **immediately freed up** and becomes available for use. ![Rate Limit Sliding Window](https://developers.etsy.com/assets/images/sliding_window_rate_limit_diagram-a89ed718930bedc79c3d8130b26950cc.png) * * * Rate Limit Headers[#](https://developers.etsy.com/documentation/essentials/rate-limits#rate-limit-headers "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------ ### Successful Response[#](https://developers.etsy.com/documentation/essentials/rate-limits#successful-response "Direct link to heading") Every successful API response includes headers detailing your application's current usage status against its allocated limits. | Header Name | Description | Example Value | | --- | --- | --- | | **`x-limit-per-second`** | The total QPS limit for your application's API key. | 150 | | **`x-remaining-this-secon`** | The remaining number of calls your application can make in the current second. | 149 | | **`x-limit-per-day`** | The total QPD limit (sliding 24-hour window) for your application's API key. | 100000 | | **`x-remaining-today`** | The remaining number of calls your application can make within the current 24-hour sliding window. | 99998 | ### Response to Exceeded Limits and Warnings[#](https://developers.etsy.com/documentation/essentials/rate-limits#response-to-exceeded-limits-and-warnings "Direct link to heading") Rate limits are evaluated in order: **QPS first, then QPD**. If either limit is exceeded, an error status `429` is returned, along with the `retry-after` header. | Header Name | Description | | --- | --- | | **`retry-after`** | The estimated time (in seconds) the client should wait before retrying a request after hitting a rate limit. | * * * Requesting Higher Limits and Recommendations[#](https://developers.etsy.com/documentation/essentials/rate-limits#requesting-higher-limits-and-recommendations "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### Request for Increased Quota[#](https://developers.etsy.com/documentation/essentials/rate-limits#request-for-increased-quota "Direct link to heading") Applications needing higher limits must contact contact us [developer@etsy.com](mailto:developer@etsy.com) to submit an upgrade request. This process requires: 1. A detailed description of the application. 2. An estimate of the required call usage (QPD/QPS). ### Optimization Recommendations[#](https://developers.etsy.com/documentation/essentials/rate-limits#optimization-recommendations "Direct link to heading") To maximize your existing quota and improve application responsiveness: * **Implement Caching:** Utilize caching strategies to minimize the number of redundant API calls. * **Handle `429` Responses:** Implement a robust retry strategy, such as **exponential backoff**, when receiving a `429` error. While the `retry-after` header provides an estimate, a strategic backoff prevents immediate retry storms. * [Rate Limits and Authentication Types](https://developers.etsy.com/documentation/essentials/rate-limits#rate-limits-and-authentication-types) * [Daily Limit Mechanism (Sliding Window Structure)](https://developers.etsy.com/documentation/essentials/rate-limits#daily-limit-mechanism-sliding-window-structure) * [How the Sliding Window Works](https://developers.etsy.com/documentation/essentials/rate-limits#how-the-sliding-window-works) * [Rate Limit Headers](https://developers.etsy.com/documentation/essentials/rate-limits#rate-limit-headers) * [Successful Response](https://developers.etsy.com/documentation/essentials/rate-limits#successful-response) * [Response to Exceeded Limits and Warnings](https://developers.etsy.com/documentation/essentials/rate-limits#response-to-exceeded-limits-and-warnings) * [Requesting Higher Limits and Recommendations](https://developers.etsy.com/documentation/essentials/rate-limits#requesting-higher-limits-and-recommendations) * [Request for Increased Quota](https://developers.etsy.com/documentation/essentials/rate-limits#request-for-increased-quota) * [Optimization Recommendations](https://developers.etsy.com/documentation/essentials/rate-limits#optimization-recommendations) --- # Multi Personalization Migration Guide | Etsy Open API v3 Multi Personalization Migration Guide[#](https://developers.etsy.com/documentation/tutorials/personalization-migration#multi-personalization-migration-guide "Direct link to heading") ======================================================================================================================================================================================= To make it easier for sellers with personalizable listings to collect the information they need from buyers and more efficiently process personalizable orders, we are replacing the single free-text personalization field with an architecture that supports multiple, typed personalization inputs: text inputs, dropdowns, and file upload questions. More information about the reasoning behind this project can be found in the [GitHub announcement](https://github.com/etsy/open-api/discussions/1530) . ### **Timeline**[#](https://developers.etsy.com/documentation/tutorials/personalization-migration#timeline "Direct link to heading") ![Multiple personalization migration timeline](https://developers.etsy.com/assets/images/perso_migration_timeline-e0162f5de9a428bbcbddd21658207662.svg) ### Integration Stages[#](https://developers.etsy.com/documentation/tutorials/personalization-migration#integration-stages "Direct link to heading") **Endpoint Migration** _(60-day migration window, Feb. 6 - Apr. 9 2026)_ * Starting **February 6th, 2026**, a new personalization data structure will be introduced, along with a new suite of personalization-specific endpoints. Third-party developers can start using the new endpoints and response/data formats for all users from day 1. * The new data structure is backwards compatible with the current personalization data. Existing listing personalization data (i.e. instructions, character limit, and required setting) will be returned in the new format (as a single text input question) and can be updated via the new endpoints. No visual changes will be required during this period. * Legacy personalization fields will be deprecated on **April 9th, 2026**, and listing create/update requests containing legacy personalization fields will return an error. **Multiple + New Question Type Support** _(early access for developer test accounts through a Developer Preview begins **Feb. 6**. The General Audience production release is slated for later in 2026, **date TBA, targeted for Late April or Early May**)_ * Listings will support up to 5 personalization questions and 3 question types: text input, dropdown, and file upload. * Third party applications that read listing personalization data must be updated to correctly display multiple personalization questions. * Applications that read personalization data on transactions may also be required to update, depending on their integration. * For applications that write personalization data, changes allowing sellers to write multiple personalization questions and/or new question types **must not be released to production users until the Etsy General Audience launch date** (TBA; date will be communicated in advance via GitHub announcements). * To facilitate development and testing prior to the General Audience launch, we will give developers early access to these features via authorized test accounts starting on **Feb. 6th, 2026**. * The file-upload question type is currently under development so it won’t be available starting Feb 6th. This feature will be available for testing on **Feb, 29, 2026**, confirmation of its release will be provided via a GitHub announcement. Consult other sections of this tutorial for detailed migration guidance, examples, and recommended steps for integrators. * [**Timeline**](https://developers.etsy.com/documentation/tutorials/personalization-migration#timeline) * [Integration Stages](https://developers.etsy.com/documentation/tutorials/personalization-migration#integration-stages) --- # Examples for the Endpoint Migration Period | Etsy Open API v3 Examples for the Endpoint Migration period[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#examples-for-the-endpoint-migration-period "Direct link to heading") =================================================================================================================================================================================================================== Getting personalization data through the dedicated personalization GET endpoint[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#getting-personalization-data-through-the-dedicated-personalization-get-endpoint "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This endpoint retrieves a listing’s personalization questions by listing ID. It returns a `personalization_questions` array. If the listing has no personalization configured, the array is empty. The following procedure retrieves the personalization questions attached to a listing. 1. Form a valid URL for `getListingPersonalization`, which must include a `listing_id`. For example, if your `listing_id` is "987654", the URL is: [https://api.etsy.com/v3/application/listings/987654/personalization](https://api.etsy.com/v3/application/listings/987654/personalization) 2. Execute a `getListingPersonalization` GET request with your x-api-key. 3. The response contains a `personalization_questions` object: { "personalization\_questions": \[\ \ {\ \ "question\_text": "Personalization",\ \ "instructions": "What name would you like engraved? Please enter their full name",\ \ "question\_id": 18205840821,\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50,\ \ "max\_allowed\_files": null\ \ }\ \ \] } Copy Getting personalization data via endpoints that return listings with associations[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#getting-personalization-data-via-endpoints-that-return-listings-with-associations "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- You can still retrieve the personalization data for a listing by using the following endpoints and including the parameter `?includes=personalization` in your requests: * [getListingsByShop](https://developers.etsy.com/documentation/reference/#operation/getListingsByShop) - `GET /v3/application/shops/{shop_id}/listings` * [getListing](https://developers.etsy.com/documentation/reference/#operation/getListing) - `GET /v3/application/listings/{listing_id}` * [getListingsByListingIds](https://developers.etsy.com/documentation/reference/#operation/getListingsByListingIds) - `GET /v3/application/listings/batch` **Example url for the `getListing` endpoint:** [https://api.etsy.com/v3/application/shops/12345678/listings?includes=personalization\\&language=en](https://api.etsy.com/v3/application/shops/12345678/listings?includes=personalization&language=en) **Example response:** During this phase we will continue to return the legacy keys related to personalization, since the new data shape is fully backwards compatible with the legacy one. { "listing\_id": 429494249, "title": "Example of personalizable listing", "is\_personalizable": true, ... // Legacy keys "personalization\_is\_required": true, "personalization\_char\_count\_max": 50, "personalization\_instructions": "Personalization\\nWhat name would you like engraved? Please enter their full name", ... // New personalization data "personalization": { "personalization\_questions": \[\ \ {\ \ "question\_text": "Personalization",\ \ "instructions": "What name would you like engraved? Please enter their full name",\ \ "question\_id": 18205840821,\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50,\ \ "max\_allowed\_files": null\ \ }\ \ \] } } Copy Adding or updating personalization data through the dedicated personalization POST endpoint[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#adding-or-updating-personalization-data-through-the-dedicated-personalization-post-endpoint "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To create or update personalization questions for a listing you must first have an existing listing. If you do not have one, you can create a new listing using the [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) endpoint before utilizing this endpoint. The following procedure creates and attaches personalization profile to a specific listing: 1. Form a valid URL for `updateListingPersonalization`, which must include a `shop_id` and a `listing_id`. For example, if your `shop_id` is "12345678", and your `listing_id` is “987654” then the `createListingPersonalization` URL would be: [https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization](https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization) 2. Build the `updateListingPersonalization` request body, which must include: 1. `personalization_questions` - Array of `personalization_questions` with a single `text_input` question and the `question_text` value must be “Personalization”, similar to: { "personalization\_questions": \[\ \ {\ \ "question\_text": "Personalization",\ \ "instructions": "What name would you like engraved? Please enter their full name",\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50\ \ }\ \ \] } Copy 3. Execute a `updateListingPersonalization` POST request with your `listings_w` scoped OAuth token and x-api-key. For example, a request with the previous `personalization_question` might look like this: * JavaScript fetch \`\`\`javascript var headers = new Headers(); headers.append("Content-Type", "application/json"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var raw = JSON.stringify({ personalization\_questions: \[\ \ {\ \ question\_text: "Personalization",\ \ instructions: "What name would you like engraved? Please enter their full name",\ \ question\_type: "text\_input",\ \ required: true,\ \ max\_allowed\_characters: 50\ \ }\ \ \] }); var requestOptions = { method: 'POST', headers: headers, body: raw, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization", requestOptions) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error)); \`\`\` Copy 4. The response would look something like this: { "personalization\_questions": \[\ \ {\ \ "question\_text": "Personalization",\ \ "instructions": "What name would you like engraved? Please enter their full name",\ \ "question\_id": 18205840821,\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50,\ \ "max\_allowed\_files": null\ \ }\ \ \] } Copy 5. The content of this request will replace any existing personalization data in this listing. Deleting personalization from a listing through the dedicated DELETE endpoint[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#deleting-personalization-from-a-listing-through-the-dedicated-delete-endpoint "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This endpoint deletes personalization for a listing. It clears personalization by setting `is_personalizable` to false and removing the listing’s personalization data. The following procedure deletes the personalization questions attached to a listing. 1. Form a valid URL for `deleteListingPersonalization`, which must include a `shop_id` and a `listing_id`. For example, if your `shop_id` is "12345678", and your `listing_id` is “987654” then the `deleteListingPersonalization` URL would be: [https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization](https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization) 2. Execute a `deleteListingPersonalization` DELETE request with your listings\_w scoped OAuth token and x-api-key. 3. Check the response. On success, the endpoint returns `204 No Content`. * [Getting personalization data through the dedicated personalization GET endpoint](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#getting-personalization-data-through-the-dedicated-personalization-get-endpoint) * [Getting personalization data via endpoints that return listings with associations](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#getting-personalization-data-via-endpoints-that-return-listings-with-associations) * [Adding or updating personalization data through the dedicated personalization POST endpoint](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#adding-or-updating-personalization-data-through-the-dedicated-personalization-post-endpoint) * [Deleting personalization from a listing through the dedicated DELETE endpoint](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples#deleting-personalization-from-a-listing-through-the-dedicated-delete-endpoint) --- # Processing Profiles Migration | Etsy Open API v3 Summary of changes[#](https://developers.etsy.com/documentation/tutorials/migration#summary-of-changes "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------- In order to provide a more granular way to distinguish between different processing times for different products inside the same listing, we are introducing **processing profiles**. Currently, in order to provide Etsy with processing time values, sellers are required to send _min\_processing\_time_ and _max\_processing\_time_ in their shipping profile requests, either through [createShopShippingProfile](https://developers.etsy.com/documentation/reference#operation/createShopShippingProfile) or [updateShopShippingProfile](https://developers.etsy.com/documentation/reference#operation/updateShopShippingProfile) . These values are always associated at listing level, which means that even if the listing has variations, all of the resulting products will have the same processing time. Processing profiles are comprised of: * `shop_id` * `readiness_state_id` (This value will be automatically assigned, users do not need to provide it) * `readiness_state` * `min_processing_time` * `max_processing_time` For the `readiness_state` parameter the possible values can be either "made\_to\_order" or "ready\_to\_ship", depending on the state a product listed is in. Each product will be linked to a specific processing profile through the `readiness_state_id`, which will give us the ability to link their processing time and readiness state values to them. After a listing’s processing times are associated with a processing profile, it can no longer be switched back to using shipping profiles. ##### important Just like shipping profiles, _requirements for a linked processing profile only applies to physical listings_. Digital listings cannot have processing profiles. ### Customer requirements[#](https://developers.etsy.com/documentation/tutorials/migration#customer-requirements "Direct link to heading") To support your customers through this new workflow, your systems will need the following capabilities: * Listing creation/updating mechanisms require the ability to set a `readiness_state_id`. * Inventory management mechanisms require the ability to optionally vary the `readiness_state_id` by one or both variation properties and set it for each product. * Mechanisms for managing processing profiles, including creation, modification, and deletion are encouraged but not required. Integration phase[#](https://developers.etsy.com/documentation/tutorials/migration#integration-phase "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------- Etsy is making this feature available to the OpenAPI developer community on July 16th. This early access period will allow you to familiarize yourselves with the new API calls and update your applications before the feature goes live to all buyers and sellers on Shop Manager and the Etsy Seller app. Third parties can continue using shipping profile processing time updates for the next 60 days, giving developers time to migrate to the new processing profiles. However, sellers won't be able to set or view processing profiles on Shop Manager until a later date. This guide will assist you in transitioning from shipping profiles to processing profiles, during this early access phase. Any Processing Profiles you create or link to listings will be considered non-production and transient. As we approach the Shop Manager and Etsy Seller app launch, Etsy will populate this data with values from sellers’ production settings. However, during the transition period, any test data created by third-party developers will not be overwritten. During this phase, Etsy advises the following: * Third-party developers **MUST** use test shops/accounts when implementing and testing the new endpoints. * This functionality should **NOT** be exposed to real users or linked to live seller accounts during this migration and testing phase. * The new features should **NOT** be made available for real seller/shop data or customer-facing workflows until Etsy officially announces a go-live date. ### Transitioning your system to use processing profiles[#](https://developers.etsy.com/documentation/tutorials/migration#transitioning-your-system-to-use-processing-profiles "Direct link to heading") To utilize the new features associated with processing profiles, you’ll need to include a `legacy=false` query parameter in API requests. This will enable the use of the new parameters and response values related to processing profiles. When using the `legacy=false` flag, API responses may include new fields related to processing profiles. Be sure to update your system to handle these new fields and structures in the API responses to ensure compatibility with the processing profile feature. Note: Usage of legacy query parameters while utilizing processing profiles via `legacy=false` will result in a 400 status code. Linking processing time to a listing or specific products[#](https://developers.etsy.com/documentation/tutorials/migration#linking-processing-time-to-a-listing-or-specific-products "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### Legacy: through shipping profiles[#](https://developers.etsy.com/documentation/tutorials/migration#legacy-through-shipping-profiles "Direct link to heading") Shipping profiles assemble shipping details such as shipping price and processing time for recipients grouped by country or region. Every listing requires a shipping profile, so you add shipping profiles to your shop with [createShopShippingProfile](https://developers.etsy.com/documentation/reference#operation/createShopShippingProfile) , and assign a shipping profile to a listing using a `shipping_profile_id` when you create or update the listing. For more details you can see the "Adding a shipping profile to a listing" section of the [listings tutorial](https://developers.etsy.com/documentation/tutorials/listings/#adding-a-shipping-profile-to-a-listing) . ### New: through processing profiles[#](https://developers.etsy.com/documentation/tutorials/migration#new-through-processing-profiles "Direct link to heading") Processing profiles contain information about the processing details of a product. Every listing requires at least one processing profile to be linked to it. You can create processing profiles for your shop with `createShopReadinessStateDefinition`, and link it to a listing using the `readiness_state_id` when you create a new listing through [`createDraftListing`](https://developers.etsy.com/documentation/reference#operation/createDraftListing) or to specific products when you update a listing's inventory through [updateListingInventory](https://developers.etsy.com/documentation/reference#operation/updateListingInventory) . #### Create a processing profile[#](https://developers.etsy.com/documentation/tutorials/migration#create-a-processing-profile "Direct link to heading") The following procedure creates a new processing profile and returns the `readiness_state_id` in the response: 1. Form a valid URL for `createShopReadinessStateDefinition`, which must include a `shop_id`. For example, if your `shop_id` is "12345678", then the _createShopReadinessStateDefinition_ URL is: [https://api.etsy.com/v3/application/shops/12345678/readiness-state-definitions](https://api.etsy.com/v3/application/shops/12345678/readiness-state-definitions) 2. Build the `createShopReadinessStateDefinition` request body, which must include: * `readiness_state`: The state a product can be in production wise, values can be either "ready\_to\_ship" or "made\_to\_order". * `min_processing_time`: The minimum time required to process to ship products with this processing profile. * `max_processing_time`: The maximum time required to process to ship products with this processing profile. * `processing_time_unit`: The unit used to represent how long a processing time is. A week is equivalent to 5 business days. Values can be "days" or "weeks". If none is provided, the unit is set to "days". 3. Execute a createShopReadinessStateDefinition POST request with your `shops_w` scoped OAuth token and `x-api-key`, and read the generated `readiness_state_id` from the response, which you’ll use to link it to specific products later on. For example, a createReadinessStateDefinition request for a product that’s made to order and the processing time is 5-8 days might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var urlencoded \= new URLSearchParams(); urlencoded.append("readiness\_state", "made\_to\_order"); urlencoded.append("min\_processing\_time", "5"); urlencoded.append("max\_processing\_time", "8"); urlencoded.append("processing\_time\_unit", "days"); var requestOptions \= { method: 'POST', headers: headers, body: urlencoded, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/readiness-state-definitions", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678/readiness-state-definitions', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'POST', CURLOPT\_POSTFIELDS \=> 'readiness\_state=made\_to\_order&min\_processing\_time=5&max\_processing\_time=8&processing\_time\_unit=days' CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy #### Link a processing profile through createDraftListing[#](https://developers.etsy.com/documentation/tutorials/migration#link-a-processing-profile-through-createdraftlisting "Direct link to heading") _This only applies to physical listings, Digital listings do not need a linked processing profile._ Once you have a `readiness_state_id` you can follow this process to _link_ a processing profile to a physical listing: 1. Form a valid URL for [`createDraftListing`](https://developers.etsy.com/documentation/reference#operation/createDraftListing) , which must include a `shop_id` for the shop that hosts the listing. For example, if your shop\_id is "12345678," the createDraftListing URL is: https://api.etsy.com/v3/application/shops/12345678/listings?legacy=false Copy The `legacy` query param is required to use processing profiles but only during the transition period. 2. Build the createDraftListing request body, which must include at a minimum: * `quantity` * `title` * `description` * `price` * `who_made` * `when_made` * `taxonomy_id` * `image_ids` required for active listings * `readiness_state_id` which you obtained through `createShopReadinessStateDefinition` 3. Execute a createDraftListing POST request with your `listings_w` scoped OAuth token and `x-api-key`. For example, a createDraftListing request to list 5 yo-yos might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var urlencoded \= new URLSearchParams(); urlencoded.append("quantity", "5"); urlencoded.append("title", "Vintage Duncan Toys Butterfly Yo-Yo, Red"); urlencoded.append("description", "Vintage Duncan Yo-Yo from 1976 with string, steel axle, and plastic body."); urlencoded.append("price", "1000"); urlencoded.append("who\_made", "someone\_else"); urlencoded.append("when\_made", "1970s"); urlencoded.append("taxonomy\_id", "1"); urlencoded.append("image\_ids", "378848,238298,030076"); urlencoded.append("readiness\_state\_id", "6752737961"); var requestOptions \= { method: 'POST', headers: headers, body: urlencoded, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/listings?legacy=false", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678/listings?legacy=false', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'POST', CURLOPT\_POSTFIELDS \=> 'quantity=5&title=Vintage%20Duncan%20Toys%20Butterfly%20Yo-Yo%2C%20Red&description=Vintage%20Duncan%20Yo-Yo%20from%201976%20with%20string%2C%20steel%20axle%2C%20and%20plastic%20body.&price=1000&who\_made=someone\_else&when\_made=1970s&taxonomy\_id=1&image\_ids=378848%2C238298%2C030076&readiness\_state\_id=6752737961' CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy Following this process will associate the processing profile with the `readiness_state_id` you provided to the listing, associating in turn the processing times and readiness state stored in the processing profile. As this endpoint doesn’t allow for the creation of variations of the same product in the same listing, such as different colored products with specific quantities or processing profiles for sale in each color, this will need to be done through the [`updateListingInventory`](https://developers.etsy.com/documentation/reference#operation/updateListingInventory) endpoint. #### Link a processing profile through updateListingInventory[#](https://developers.etsy.com/documentation/tutorials/migration#link-a-processing-profile-through-updatelistinginventory "Direct link to heading") The following example updates a listing inventory where there are two variations: 1. Material - "Pine", "Walnut" 2. Size - "4", "5" In this example, the material variation affects the price, while the size variation affects the quantity and sku of the product. In the products array, you will have 4 entries (2 materials x 2 sizes). Due to the size affecting both quantity and sku, when quantity is updated it must be the same value across all products sharing the same sku. The sku "woodthing4" has 2 entries in the array, but the `quantity` value for all three of those arrays (inside `offerings`) must be the same value (44 in this example). Similarly, because material affects pricing, in each product you will see that the "Walnut" property value indicates the `price` in `offerings` is 8.00 while "Pine" is 6.00. Note that since there is only one variation that affects the price, the `price_on_property` value is a single value of `507`, which is the property\_id for "Material". Since size affects both quantity and sku, the `quantity_on_property` and `sku_on_property` values are a single value of `100`, which is the property\_id for "Size". Now, there are two possible approaches to take with processing profiles: 1. Processing profiles vary per product. 2. The same processing profile can be linked to all the products inside the listing. We'll explore how to provide those values in the following examples. #### Processing profiles vary per product[#](https://developers.etsy.com/documentation/tutorials/migration#processing-profiles-vary-per-product "Direct link to heading") Following the example above, let's add to the example that the `processing profiles` vary per material, just like `price`. In Etsy's Shop Manager web UI this distribution would look like this: ![img alt](https://developers.etsy.com/assets/images/readiness_state_definition_example_vary_per_product-a00d0cb74248a0cde0283d52658b28ee.png) To obtain the available processing profiles for the shop and their corresponding `readiness_state_id` to link it to the specific products you can use the `getShopReadinessStateDefinitions` endpoint. For this example we'll use two different processing profiles for the two different materials the seller offers with the following values: | Material: Pine | Material: Walnut | | --- | --- | | `readiness_state_id`: 18201076875 | `readiness_state_id`: 18201056977 | | `readiness_state`: mate\_to\_order | `readiness_state`: mate\_to\_order | | `min_processing_time`: 3 | `min_processing_time`: 4 | | `max_processing_time`: 5 | `max_processing_time`: 6 | | `processing_time_unit`: weeks | `processing_time_unit`: days | Once we have the `readiness_state_id` for each of the profiles we want to use for these products we can include them in the body request for the [`updateListingInventory`](https://developers.etsy.com/documentation/reference#operation/updateListingInventory) endpoint, which would be structured like this: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/json"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var productsArray \= { "products": \[\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201056977\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201056977\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ }\ \ \], "price\_on\_property": \[507\], "quantity\_on\_property": \[100\], "sku\_on\_property": \[100\], "readiness\_state\_on\_property": \[507\], }; var requestOptions \= { method: 'PUT', headers: headers, body: JSON.stringify(productsArray), redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/listings/192837465/inventory?legacy=false", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/listings/192837465/inventory?legacy=false', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'PUT', CURLOPT\_POSTFIELDS \=>'{ "products": \[\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201056977\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201056977\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ }\ \ \], "price\_on\_property": \[507\], "quantity\_on\_property": \[100\], "sku\_on\_property": \[100\] "readiness\_state\_on\_property": \[507\], }', CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/json', 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy As you can see in the above example, since `processing profiles` vary by the material property like `price`, we'll add a `readiness_state_on_property` value with the property\_id corresponding to "Material" (`507`). Each product offering will have an associated `readiness_state_id`, in this case the same `readiness_state_id` needs to be used for all the offerings that have the same material. We have two offerings for each material, lets take “Walnut” as an example: 1. Walnut - Size 4 2. Walnut - Size 5 Since they all share the “Walnut” property value they will use the same processing profile. #### The same processing profile is used for all the products[#](https://developers.etsy.com/documentation/tutorials/migration#the-same-processing-profile-is-used-for-all-the-products "Direct link to heading") In this case the body request for the [updateListingInventory](https://developers.etsy.com/documentation/reference#operation/updateListingInventory) endpoint would be pretty similar to the case above, with two main differences: 1. The same `readiness_state_id` will be used for all the product offerings. 2. The `readiness_state_on_property` value will be empty, as none of the properties that change the readiness state of the product. **NOTES:** 1. When updating inventory, the entire set of products (based on variations) must be in the `products` array. 2. To get the product array, call `getListingInventory` for the listing. From the `getListingInventory` response, remove the following fields: `product_id`, `offering_id`, `scale_name`, `is_deleted` and `value_pairs`. Also change the `price` array in offerings to be a decimal value instead of an array. 3. The `*_on_property` values should match the `property_id` values, but only if those properties affect the price, quantity, sku, or processing profiles. See the sample below for handling variations. Get processing time values[#](https://developers.etsy.com/documentation/tutorials/migration#get-processing-time-values "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------- ### Legacy: through shipping profiles[#](https://developers.etsy.com/documentation/tutorials/migration#legacy-through-shipping-profiles-1 "Direct link to heading") You can get the processing time values associated with a listing through the [getListing](https://developers.etsy.com/documentation/reference#operation/getListing) endpoint if you have a `listing_id`. The response will show the associated shipping profile and its values, including the processing time. If you have a specific `shipping_profile_id` you can use the [getShopShippingProfile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile) endpoint to obtain the `min_processing_days` and `max_processing_days`. ### New: through processing profiles[#](https://developers.etsy.com/documentation/tutorials/migration#new-through-processing-profiles-1 "Direct link to heading") You’ll be able to access the `readiness_state_id` associated with specific products through [getListingInventory](https://developers.etsy.com/documentation/reference#operation/getListingInventory) , [getListingOffering](https://developers.etsy.com/documentation/reference#operation/getListingOffering) or [getListingProduct](https://developers.etsy.com/documentation/reference#operation/getListingProduct) , where you’ll find the linked `readiness_state_id` inside the product offerings. You can use the endpoint [getShopReadinessStateDefinition](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinition) with the `readiness_state_id` and `shop_id` to retrive the specific processing time values associated with that profile. To get the processing profiles associated with a shop, you can use the endpoint [getShopReadinessStateDefinitions](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinitions) using the `shop_id`. The response on this endpoint will return a list of all the processing profiles, and will include the processing time values for each one of them. To get the processing profiles associated with a shop, you can use the endpoint [getShopReadinessStateDefinitions](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinitions) using the `shop_id`. The response on this endpoint will return a list of all the processing profiles, and will include the processing time values for each one of them. Update processing time values[#](https://developers.etsy.com/documentation/tutorials/migration#update-processing-time-values "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------- ### Legacy: through shipping profiles[#](https://developers.etsy.com/documentation/tutorials/migration#legacy-through-shipping-profiles-2 "Direct link to heading") To update processing time in shipping profiles currently you need to use the [updateShopShippingProfile](https://developers.etsy.com/documentation/reference#operation/updateShopShippingProfile) endpoint and provide new `min_processing_time`, `max_processing_time` and `processing_time_unit` with the new values. ### New: through processing profiles[#](https://developers.etsy.com/documentation/tutorials/migration#new-through-processing-profiles-2 "Direct link to heading") When using processing profiles you’ll need to use the `updateShopReadinessStateDefinition`, which will update an existing processing profile. The fields `shop_id` and `readiness_state_id` are required, while the fields `readiness_state`, `min_processing_time`, and `max_processing_time`, `processing_time_unit` would be optional. Keep in mind that this update will apply to all product offerings that are linked to the processing profile. * [Summary of changes](https://developers.etsy.com/documentation/tutorials/migration#summary-of-changes) * [Customer requirements](https://developers.etsy.com/documentation/tutorials/migration#customer-requirements) * [Integration phase](https://developers.etsy.com/documentation/tutorials/migration#integration-phase) * [Transitioning your system to use processing profiles](https://developers.etsy.com/documentation/tutorials/migration#transitioning-your-system-to-use-processing-profiles) * [Linking processing time to a listing or specific products](https://developers.etsy.com/documentation/tutorials/migration#linking-processing-time-to-a-listing-or-specific-products) * [Legacy: through shipping profiles](https://developers.etsy.com/documentation/tutorials/migration#legacy-through-shipping-profiles) * [New: through processing profiles](https://developers.etsy.com/documentation/tutorials/migration#new-through-processing-profiles) * [Get processing time values](https://developers.etsy.com/documentation/tutorials/migration#get-processing-time-values) * [Legacy: through shipping profiles](https://developers.etsy.com/documentation/tutorials/migration#legacy-through-shipping-profiles-1) * [New: through processing profiles](https://developers.etsy.com/documentation/tutorials/migration#new-through-processing-profiles-1) * [Update processing time values](https://developers.etsy.com/documentation/tutorials/migration#update-processing-time-values) * [Legacy: through shipping profiles](https://developers.etsy.com/documentation/tutorials/migration#legacy-through-shipping-profiles-2) * [New: through processing profiles](https://developers.etsy.com/documentation/tutorials/migration#new-through-processing-profiles-2) --- # Endpoint Migration (backwards compatible) | Etsy Open API v3 Endpoint Migration (backwards compatible)[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#endpoint-migration-backwards-compatible "Direct link to heading") ====================================================================================================================================================================================================== We are introducing a new data structure for listing personalization, as well as a new suite of endpoints to manage this data. This new structure is designed to maintain backwards compatibility with the existing listing personalization data, which will be modeled as a single text input question. ##### tip **How to test:** Use your normal process and be sure to follow these [guidelines](https://www.etsy.com/legal/policy/api-testing-policy/169130941112) . **When to release:** Since these changes are backwards compatible, you can release them to your users whenever you’ve finished development work. Keep in mind that POST requests will be enabled only for a single text question per listing during this period, writes of multiple and new question types will be allowed later in 2026. **The legacy personalization fields will be deprecated on April 9th, 2026; your integration must be updated before then to avoid errors or missing data.** Required Changes[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#required-changes "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------ ### If you read personalization data:[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#if-you-read-personalization-data "Direct link to heading") * Update your integration to use the new personalization data structure (details below). * Fetch listing personalization data via the new `getListingPersonalization` endpoint or by calling one of the following endpoints with `personalization` in the `includes` query param: [getListingsByShop](https://developers.etsy.com/documentation/reference/#operation/getListingsByShop) , [getListing](https://developers.etsy.com/documentation/reference/#operation/getListing) , or [getListingsByListingIds](https://developers.etsy.com/documentation/reference/#operation/getListingsByListingIds) . * The `is_personalizable` property will continue to be returned from the current listing endpoints. ### If you write personalization data:[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#if-you-write-personalization-data "Direct link to heading") * Update your integration to use the new personalization POST and DELETE endpoints (`updateListingPersonalization` and `deleteListingPersonalization`). Expect requests to the new POST endpoint to fully replace existing personalization data. * Stop sending legacy personalization fields on listing create and update requests. Migration Details[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#migration-details "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------------------------- The following sections detail the differences between the current and new behavior. You can consult the [Examples for the Endpoint Migration period](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration-examples) section to see detailed examples. ### Reading listing personalization data[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#reading-listing-personalization-data "Direct link to heading") Currently, listing personalization data is returned in the `is_personalizable`, `personalization_is_required`, `personalization_char_count_max`, and `personalization_instructions` fields from the following endpoints: * [getListingsByShop](https://developers.etsy.com/documentation/reference/#operation/getListingsByShop) - `GET /v3/application/shops/{shop_id}/listings` * [getListing](https://developers.etsy.com/documentation/reference/#operation/getListing) - `GET /v3/application/listings/{listing_id}` * [getListingInventory](https://developers.etsy.com/documentation/reference/#operation/getListingInventory) - `GET /v3/application/listings/{listing_id}/inventory` using `?includes=Listing` * [getListingsByListingIds](https://developers.etsy.com/documentation/reference/#operation/getListingsByListingIds) - `GET /v3/application/listings/batch` * [findAllListingsActive](https://developers.etsy.com/documentation/reference/#operation/findAllListingsActive) - `GET /v3/application/listings/active` * [findAllActiveListingsByShop](https://developers.etsy.com/documentation/reference/#operation/findAllActiveListingsByShop) - `GET /v3/application/shops/{shop_id}/listings/active` * [getFeaturedListingsByShop](https://developers.etsy.com/documentation/reference/#operation/getFeaturedListingsByShop) - `GET /v3/application/shops/{shop_id}/listings/featured` * [getListingsByShopSectionId](https://developers.etsy.com/documentation/reference/#operation/getListingsByShopSectionId) - `GET /v3/application/shops/{shop_id}/shop-sections/listings` * [getListingsByShopReceipt](https://developers.etsy.com/documentation/reference/#operation/getListingsByShopReceipt) - `GET /v3/application/shops/{shop_id}/receipts/{receipt_id}/listings` * [getListingsByShopReturnPolicy](https://developers.etsy.com/documentation/reference/#operation/getListingsByShopReturnPolicy) - `GET /v3/application/shops/{shop_id}/policies/return/{return_policy_id}/listings` ##### note We will continue to return the `is_personalizable` property as part of the base listing data returned from these endpoints. #### New: Through the dedicated personalization GET endpoint[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#new-through-the-dedicated-personalization-get-endpoint "Direct link to heading") We are introducing a new `getListingPersonalization` endpoint (`GET https://api.etsy.com/v3/application/listings/{listing_id}/personalization`) to fetch personalization data by `listing_id`. It returns a `personalization_questions` array. If the listing has no personalization configured, the array is empty. This endpoint will return existing listing personalization data in the following structure: { "personalization\_questions": \[\ \ {\ \ "question\_type": "text\_input",\ \ "question\_text": "Personalization",\ \ "instructions": string,\ \ "required": bool,\ \ "max\_allowed\_characters": int\ \ }\ \ \] } Copy ##### note During the initial migration phase (before the start of the Multiple + New Question Type Support period), you can expect listings to have at most one `text_input` type question with the `question_text` “Personalization.” #### New: Via endpoints that return listings with associations[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#new-via-endpoints-that-return-listings-with-associations "Direct link to heading") Additionally, you can retrieve the personalization data for a listing from the following endpoints by appending the `?includes=personalization` query param: * [getListingsByShop](https://developers.etsy.com/documentation/reference/#operation/getListingsByShop) - `GET /v3/application/shops/{shop_id}/listings` * [getListing](https://developers.etsy.com/documentation/reference/#operation/getListing) - `GET /v3/application/listings/{listing\_id}` * [getListingsByListingIds](https://developers.etsy.com/documentation/reference/#operation/getListingsByListingIds) - `GET /v3/application/listings/batch` The response body will include a `personalization` key, containing a possibly empty `personalization_questions` array. We will continue to return the `is_personalizable` property as part of the base listing level: { "is\_personalizable": bool, "personalization": { "personalization\_questions": \[\ \ {\ \ "question\_type": "text\_input",\ \ "question\_text": "Personalization",\ \ "instructions": string,\ \ "required": bool,\ \ "max\_allowed\_characters": int\ \ }\ \ \] } ... } Copy ### Adding or updating listing personalization data[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#adding-or-updating-listing-personalization-data "Direct link to heading") Currently, you can add or update personalization on a listing using the [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) and the [`updateListing`](https://developers.etsy.com/documentation/reference/#operation/updateListing) endpoints by sending the following params: `is_personalizable`, `personalization_is_required`, `personalization_char_count_max`, and `personalization_instructions`. #### New: Through the dedicated personalization POST endpoint[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#new-through-the-dedicated-personalization-post-endpoint "Direct link to heading") The new `updateListingPersonalization` endpoint (`POST https://api.etsy.com/v3/application/shops/{shop_id}/listings/{listing_id}/personalization`) creates or updates personalization data for a listing. ##### note This endpoint fully replaces the existing listing personalization data on the listing with the sent data. Current personalization data can be modeled as a single `text_input` question: { "personalization\_questions": \[\ \ {\ \ "question\_type": "text\_input",\ \ "question\_text": "Personalization",\ \ "instructions": string, // must be 120 characters or fewer\ \ "required": bool,\ \ "max\_allowed\_characters": int // must be between 1 and 1024\ \ }\ \ \] } Copy ##### info Before the Multiple + New Question Type Support period starts, POST requests for production seller accounts must follow the following constraints: * The `personalization_question` array must contain one question object. * The `question_type` must be `text_input.` * To preserve compatibility with legacy UIs, which do not include a configurable title field, **please send '`Personalization`' as the default `question_text` value during the endpoint migration phase**. Once multiple personalization questions are introduced (General Audience launch), this field can be configured by the seller and will be used as the title of each question. ### Deleting personalization from a listing[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#deleting-personalization-from-a-listing "Direct link to heading") Currently, to remove personalization from a listing, you can set `is_personalizable` to `false` via the `updateListing` endpoint. #### New: Through the dedicated personalization DELETE endpoint[#](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#new-through-the-dedicated-personalization-delete-endpoint "Direct link to heading") The new `deleteListingPersonalization` endpoint (`DELETE https://api.etsy.com/v3/application/shops/{shop_id}/listings/{listing_id}/personalization`) can be used to turn off personalization for a listing and remove the associated data. The `is_personalizable` property will be set to `false` on the main listing record as a result of this action. * [Required Changes](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#required-changes) * [If you read personalization data:](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#if-you-read-personalization-data) * [If you write personalization data:](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#if-you-write-personalization-data) * [Migration Details](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#migration-details) * [Reading listing personalization data](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#reading-listing-personalization-data) * [Adding or updating listing personalization data](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#adding-or-updating-listing-personalization-data) * [Deleting personalization from a listing](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration#deleting-personalization-from-a-listing) --- # Multiple + New Question Type Support | Etsy Open API v3 Multiple + New Question Type Support[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#multiple--new-question-type-support "Direct link to heading") ================================================================================================================================================================================================================= Later in 2026 (General Audience release date TBA), we will roll out new personalization features to sellers, allowing them to configure up to 5 personalization questions on a listing using 3 question types: text input (introduced during the Endpoint Migration period), dropdown, and file upload. ##### danger The ability to write multiple questions and/or new question types **must not be released to production users** until the Etsy.com General Audience release (date TBA). To facilitate development and testing prior to the General Audience launch, we will give developers early access to these features via authorized test accounts starting on **Feb. 6th** (a.k.a. “developer preview”). ##### info **Developer Preview** To access the Multiple + New Question Type Support changes prior to the General Audience launch, external developers must use a seller account in **developer mode**. Use the following links while logged in to the account you intend to use for testing to get your account set up: * **To get your shop in developer mode:** Visit [https://www.etsy.com/developers/shop](https://www.etsy.com/developers/shop) * **To register for the Developer Preview:** Visit [https://www.etsy.com/your/shops/me/dashboard?enroll-seller-perso-closed-beta=true](https://www.etsy.com/your/shops/me/dashboard?enroll-seller-perso-closed-beta=true) If you’ve successfully registered for Developer Preview you’ll see a green success toast and will have immediate access to the feature. If the enrollment failed, you’ll see a red failure toast. ![Developer Preview success toast](https://developers.etsy.com/img/green_success_toast.png) If you’re looking for more information about how to use personalization features in Etsyweb, be sure to check out the Help Center article: [How to Offer Personalized Listings as a Beta Participant](https://help.etsy.com/hc/en-us/articles/33478801738519-How-to-Offer-Personalized-Listings-as-a-Beta-Participant?segment=selling) . For more detailed examples refer to the [Examples for the Multiple + New Questions Type Support Period](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples) section. Required changes[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#required-changes "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To ensure your integration is compatible with the new personalization features, you **must** make the following changes. These updates should be released to users as soon as possible after Etsy’s General Audience launch (date TBA). #### If you read personalization data on transactions:[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#if-you-read-personalization-data-on-transactions "Direct link to heading") * Personalization data will continue to be returned in the transaction `variation` array in the existing format. If your integration relies on the `formatted_name` being "`Personalization`" or there being one item with `property_id: 54`, this may need to be updated. #### If you read personalization data on listings:[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#if-you-read-personalization-data-on-listings "Direct link to heading") * Your integration will need to be updated to correctly display multiple questions with new types (test input, dropdown, and file-upload). #### If you write personalization data on listings:[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#if-you-write-personalization-data-on-listings "Direct link to heading") * Your integration will need to be updated to support adding multiple questions with new question types. Breakdown of the changes[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#breakdown-of-the-changes "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ With multiple and new question types, we aim to streamline the purchasing experience for personalized items by reducing the amount of text buyers need to read when making a purchase. As part of this update, we are introducing a new **120 character limit to the `instructions` field** (reduced from the previous 256 character limit). Please review the following sections to understand how this change may affect your application. ### Reading transaction personalization data[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#reading-transaction-personalization-data "Direct link to heading") Currently, personalization data for a transaction is returned (if present) as part of the `variations` array on a transaction object: { ... // other transaction data "variations": \[\ \ ... // other variation data\ \ {\ \ "formatted\_name": "Personalization",\ \ "formatted\_value": string,\ \ "property\_id": 54,\ \ "value\_id": int|null\ \ }\ \ \] } Copy Transaction personalization will continue to be returned in the same format, but be advised of the following changes: * The `formatted_name` may be a seller-configured value. * There may be multiple objects with `property_id` 54. * For file uploads, the `formatted_value` will be a URL. ### Reading listing personalization data[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#reading-listing-personalization-data "Direct link to heading") As specified in the [Endpoint Migration](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration) section of the guide, listing personalization data can be fetched via the following endpoints: * getListingPersonalization - `GET /v3/application/listings/{listing_id}/personalization` * [getListingsByShop](https://developers.etsy.com/documentation/reference/#operation/getListingsByShop) - `GET /v3/application/shops/{shop_id}/listings?includes=personalization` * [getListing](https://developers.etsy.com/documentation/reference/#operation/getListing) - `GET /v3/application/listings/{listing_id}?includes=personalization` * [getListingsByListingIds](https://developers.etsy.com/documentation/reference/#operation/getListingsByListingIds) - `GET /v3/application/listings/batch?includes=personalization` The `personalization_questions` array may contain up to 5 questions with 3 types: text input, dropdown, and file upload. The question data structure introduced in the Endpoint Migration will be extended to encompass the new question types: { "question\_id": int, "question\_type": ENUM // "text\_input", "dropdown", "unlabeled\_upload", "labeled\_upload" "question\_text": string, "instructions": string, // only applicable to text\_input and upload questions "required": bool, "max\_allowed\_characters": int, // only applicable to text\_input questions "max\_allowed\_files": int, // only applicable to upload questions "options": \[ // applicable for dropdowns and labeled\_upload questions\ \ {\ \ "option\_id": int,\ \ "label": string\ \ }\ \ \] } Copy Examples of each question type are given in the [Examples for the Multiple + New Question Type Support Period](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples) section. Existing `instructions` values that exceed the 120 character limit will still be returned in full by GET requests and will not be automatically truncated. However, any updates to these questions via POST requests must comply with the new 120 character limit. ### Writing listing personalization data[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#writing-listing-personalization-data "Direct link to heading") As specified in the [Endpoint Migration](https://developers.etsy.com/documentation/tutorials/personalization/endpoint-migration) section of this guide, listing personalization can be written via the `updatePersonalizationEndpoint` endpoint (`POST https://api.etsy.com/v3/application/shops/{shop_id}/listings/{listing_id}/personalization`). For authorized developer test accounts during the **Developer Preview** period, and for all production seller accounts following the General Audience launch, this endpoint will accept an array of up to 5 `personalization_questions` and support all question types. { "personalization\_questions": \[\ \ {\ \ "question\_id": int,\ \ "question\_type": ENUM // "text\_input", "dropdown", "unlabeled\_upload", "labeled\_upload"\ \ "question\_text": string,\ \ "instructions": string, // only allowed for text\_input and upload questions, limited to 120 characters\ \ "required": bool,\ \ "max\_allowed\_characters": int, // required for text\_input questions\ \ "max\_allowed\_files": int, // required for upload questions\ \ "options": \[ // required for dropdowns and labeled\_upload questions\ \ {\ \ "label": string\ \ }\ \ \]\ \ },\ \ ...\ \ \] } Copy Please note the following constraints: * The `personalization_questions` array must contain between 1 and 5 elements. * At most one upload-type question (either `unlabeled_upload` or `labeled_upload`) may be sent per listing. ##### warning **When you release the update to support multiple questions and new question types, please also append `?supports_multiple_personalization_questions=true` when calling this endpoint.** This will allow us to track adoption and prevent inadvertent overwrites of seller data from non-updated apps. Without this query param, attempts to write data that would delete previously configured personalization questions will fail with a `409 Conflict` error. **Adding the param without updating your application can lead to deleting data provided by the seller on Etsyweb.** There are also field-level constraints: * `question_text` * Must be between 1 and 45 characters * `instructions` * Must be empty or `null` for dropdowns * Optional for the other question types * Must not exceed 120 characters when provided (requests will fail validation otherwise) * `max_allowed_characters` * Required for `text_input` questions; not allowed for other question types * Must be between 1 and 1024 * `max_allowed_files` * Required for upload questions (either labeled or unlabeled); not allowed for other question types * Must be between 1 and 10 * `options` * Required for `dropdown` and `labeled_upload` questions; not allowed for other question types * For dropdowns: * Must contain 1 - 30 options * Each label must be 1 - 20 characters * For labeled uploads: * Length must equal `max_allowed_files` * Each label must be 1 - 45 characters * `question_id` * optional, but encouraged if you are updating or adding to existing personalization on a listing ([example](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#updating-a-listing-with-existing-personalization) ) * [Required changes](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#required-changes) * [Breakdown of the changes](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#breakdown-of-the-changes) * [Reading transaction personalization data](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#reading-transaction-personalization-data) * [Reading listing personalization data](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#reading-listing-personalization-data) * [Writing listing personalization data](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support#writing-listing-personalization-data) --- # Examples for the Multiple + New Questions Type Support Period | Etsy Open API v3 Examples for the Multiple + New Questions Type Support Period[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#examples-for-the-multiple--new-questions-type-support-period "Direct link to heading") ============================================================================================================================================================================================================================================================================ Examples of new question types[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#examples-of-new-question-types "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### Dropdown questions[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#dropdown-questions "Direct link to heading") { "question\_text": "Font", "question\_type": "dropdown", "options": \[\ \ {\ \ "label": "Arial"\ \ },\ \ {\ \ "label": "Century Gothic"\ \ },\ \ {\ \ "label": "Times New Roman"\ \ }\ \ \], "required": true } Copy ### Unlabeled file uploads[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#unlabeled-file-uploads "Direct link to heading") { "question\_text": "Family pictures", "instructions": "Add images of the members of the family members that you want in your family portrait", "question\_type": "unlabeled\_upload", "required": true, "max\_allowed\_files": 10 } Copy ### Labeled file uploads[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#labeled-file-uploads "Direct link to heading") { "question\_text": "Family pictures", "instructions": "Add images of the members of the family members that you want in your family portrait", "question\_type": "labeled\_upload", "options": \[\ \ {\ \ "label": "Dad"\ \ },\ \ {\ \ "label": "Mom"\ \ },\ \ {\ \ "label": "Children"\ \ }\ \ \], "required": true, "max\_allowed\_files": 3 } Copy ##### note For labeled file upload questions, the `max_allowed_files` value must match the number of labels provided in the `options` array. Adding multiple personalization questions to a listing[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#adding-multiple-personalization-questions-to-a-listing "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To create or update personalization questions for a listing you must first have an existing listing. If you do not have one, you can create a new listing using the [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) endpoint before utilizing this endpoint. During the Developer Preview and after the General Audience launch (if you’ve updated your application to support multiple questions), you **must** include the query parameter `?supports_multiple_personalization_questions=true` in your request to successfully update the listing. If this parameter is omitted or incorrect, the request will result in a `409 Conflict` response. **Adding the param without updating the application can lead to deleting data provided by the seller on Etsyweb**. The following procedure creates and attaches personalization profile to a specific listing with the maximum number of personalization questions allowed and an unlabeled file upload question: 1. Form a valid URL for `updateListingPersonalization`, which must include a `shop_id` and a `listing_id` and include a `?supports_multiple_personalization_questions=true` param. For example, if your `shop_id` is "12345678", and your `listing_id` is “987654” then the `createListingPersonalization` URL would be: [https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization?supports\_multiple\_personalization\_questions=true](https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization?supports_multiple_personalization_questions=true) 2. Build the `updateListingPersonalization` request body, which must include: 1. `personalization_questions` - Array of question objects, with the following shape: { "personalization\_questions": \[\ \ {\ \ "question\_text": "What name would you like engraved?",\ \ "instructions": "Please enter your family lastname",\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50\ \ },\ \ {\ \ "question\_text": "What message would you like in the card?",\ \ "instructions": "Please enter the message you would like added in the giftcard.",\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 680\ \ },\ \ {\ \ "question\_text": "Family pictures",\ \ "instructions": "Add images of the members of your family that you want in your family portrait",\ \ "question\_type": "unlabeled\_upload",\ \ "required": true,\ \ "max\_allowed\_files": 10\ \ },\ \ {\ \ "question\_text": "Font",\ \ "question\_type": "dropdown",\ \ "options": \[\ \ {\ \ "label": "Arial"\ \ },\ \ {\ \ "label": "Century Gothic"\ \ },\ \ {\ \ "label": "Times New Roman"\ \ }\ \ \],\ \ "required": true\ \ },\ \ {\ \ "question\_text": "Frame color",\ \ "question\_type": "dropdown",\ \ "options": \[\ \ {\ \ "label": "Dark browk"\ \ },\ \ {\ \ "label": "Light brown"\ \ },\ \ {\ \ "label": "White"\ \ },\ \ {\ \ "label": "Black"\ \ }\ \ \],\ \ "required": true\ \ }\ \ \] } Copy 3. Execute a `updateListingPersonalization` POST request with your `listings_w` scoped OAuth token and x-api-key. For example, a request with the previous `personalization_question` might look like this: * JavaScript fetch \`\`\`javascript var headers = new Headers(); headers.append("Content-Type", "application/json"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var raw = JSON.stringify({ "personalization\_questions": \[\ \ {\ \ "question\_text": "What name would you like engraved?",\ \ "instructions": "Please enter your family lastname",\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50\ \ },\ \ {\ \ "question\_text": "What message would you like in the card?",\ \ "instructions": "Please enter the message you would like added in the giftcard.",\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 680\ \ },\ \ {\ \ "question\_text": "Family pictures",\ \ "instructions": "Add images of the members of your family that you want in your family portrait",\ \ "question\_type": "unlabeled\_upload",\ \ "required": true,\ \ "max\_allowed\_files": 10\ \ },\ \ {\ \ "question\_text": "Font",\ \ "question\_type": "dropdown",\ \ "options": \[\ \ {\ \ "label": "Arial"\ \ },\ \ {\ \ "label": "Century Gothic"\ \ },\ \ {\ \ "label": "Times New Roman"\ \ }\ \ \],\ \ "required": true\ \ },\ \ {\ \ "question\_text": "Frame color",\ \ "question\_type": "dropdown",\ \ "options": \[\ \ {\ \ "label": "Dark brown"\ \ },\ \ {\ \ "label": "Light brown"\ \ },\ \ {\ \ "label": "White"\ \ },\ \ {\ \ "label": "Black"\ \ }\ \ \],\ \ "required": true\ \ }\ \ \] }); var requestOptions = { method: 'POST', headers: headers, body: raw, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization", requestOptions) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error)); \`\`\` Copy 4. You should get a `201 Created` response that would look similar to this: { "personalization\_questions": \[\ \ {\ \ "question\_text": "What name would you like engraved?",\ \ "instructions": "Please enter your family lastname",\ \ "question\_id": 18205669682,\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50,\ \ "max\_allowed\_files": null\ \ },\ \ {\ \ "question\_text": "What message would you like in the card?",\ \ "instructions": "Please enter the message you would like added in the giftcard.",\ \ "question\_id": 18205669686,\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 680,\ \ "max\_allowed\_files": null\ \ },\ \ {\ \ "question\_text": "Family pictures",\ \ "instructions": "Add images of the members of your family that you want in your family portrait",\ \ "question\_id": 18205849779,\ \ "question\_type": "unlabeled\_upload",\ \ "required": true,\ \ "max\_allowed\_characters": null,\ \ "max\_allowed\_files": 10\ \ },\ \ {\ \ "question\_text": "Font",\ \ "instructions": null,\ \ "question\_id": 18205849781,\ \ "question\_type": "dropdown",\ \ "required": true,\ \ "max\_allowed\_characters": null,\ \ "max\_allowed\_files": null,\ \ "options": \[\ \ {\ \ "option\_id": 18205669694,\ \ "label": "Arial"\ \ },\ \ {\ \ "option\_id": 18205849785,\ \ "label": "Century Gothic"\ \ },\ \ {\ \ "option\_id": 18205669696,\ \ "label": "Times New Roman"\ \ }\ \ \]\ \ },\ \ {\ \ "question\_text": "Frame color",\ \ "instructions": null,\ \ "question\_id": 18205849787,\ \ "question\_type": "dropdown",\ \ "required": true,\ \ "max\_allowed\_characters": null,\ \ "max\_allowed\_files": null,\ \ "options": \[\ \ {\ \ "option\_id": 18205849789,\ \ "label": "Dark browk"\ \ },\ \ {\ \ "option\_id": 18205849791,\ \ "label": "Light brown"\ \ },\ \ {\ \ "option\_id": 18205849793,\ \ "label": "White"\ \ },\ \ {\ \ "option\_id": 18205849795,\ \ "label": "Black"\ \ }\ \ \]\ \ }\ \ \] } Copy Updating a listing with existing personalization[#](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#updating-a-listing-with-existing-personalization "Direct link to heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- When updating personalization on a listing, please be aware that the payload should contain **all the personalization information** that you want on the listing, as the POST request will replace the existing listing personalization data. If the update includes existing questions - for instance, if you are adding an additional question to existing ones – please include the `question_id` for each of the existing questions in your POST request to the `updateListingPersonalization` endpoint. The following procedure updates listing personalization with an existing question: 1. Obtain the `question_id` through the `getListingPersonalization` GET endpoint, a valid url must include a `listing_id`. For example, if your `listing_id` is "987654", the URL is: [https://api.etsy.com/v3/application/listings/987654/personalization](https://api.etsy.com/v3/application/listings/987654/personalization) 2. Read the `question_id` value from the response. { "personalization\_questions": \[\ \ {\ \ "question\_text": "What name would you like engraved?",\ \ "instructions": "Please enter your family lastname",\ \ "question\_id": 1458181502381,\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50,\ \ "max\_allowed\_files": null\ \ }\ \ \] } Copy 3. Form a valid URL for `updateListingPersonalization`, which must include a `shop_id` and a `listing_id` and include a `?supports_multiple_personalization_questions=true` param. For example, if your `shop_id` is "12345678", and your `listing_id` is “987654” then the `createListingPersonalization` URL would be: [https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization?supports\_multiple\_personalization\_questions=true](https://api.etsy.com/v3/application/shops/12345678/listings/987654/personalization?supports_multiple_personalization_questions=true) 4. Build the `updateListingPersonalization` request body, which must include: 1. `personalization_questions` - Array of question objects, each question should include its `question_id` if you’re editing an existing question: { "personalization\_questions": \[\ \ {\ \ "question\_text": "What name would you like engraved?", // existing question\ \ "instructions": "Please enter your family lastname",\ \ "question\_id": 1458181502381,\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 50,\ \ },\ \ {\ \ "question\_text": "Font", // new question\ \ "question\_type": "drodpown",\ \ "required": true,\ \ "options": \[\ \ {\ \ "label": "Arial"\ \ },\ \ {\ \ "label": "Century Gothic"\ \ },\ \ {\ \ "label": "Times New Roman"\ \ }\ \ \]\ \ }\ \ \] } Copy 5. Execute a `updateListingPersonalization` POST request with your `listings_w` scoped OAuth token and x-api-key, similar to the example above. 6. You should get a `201 Created` response that would look similar to this: { "personalization\_questions": \[\ \ {\ \ "question\_text": "What names would you like engraved?",\ \ "instructions": "Please enter the names of your family members.",\ \ "question\_id": 1458184327757,\ \ "question\_type": "text\_input",\ \ "required": true,\ \ "max\_allowed\_characters": 100,\ \ "max\_allowed\_files": null\ \ },\ \ {\ \ "question\_text": "Font",\ \ "question\_type": "drodpown",\ \ "question\_id": 1458184327768,\ \ "required": true,\ \ "options": \[\ \ {\ \ "option\_id": 18205849800,\ \ "label": "Arial"\ \ },\ \ {\ \ "option\_id": 18205849801,\ \ "label": "Century Gothic"\ \ },\ \ {\ \ "option\_id": 18205849802,\ \ "label": "Times New Roman"\ \ }\ \ \]\ \ }\ \ \] } Copy 7. Keep in mind that the `question_id` is not stable and it might change in a successful response if Etsy detects any changes to the current question. * [Examples of new question types](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#examples-of-new-question-types) * [Dropdown questions](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#dropdown-questions) * [Unlabeled file uploads](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#unlabeled-file-uploads) * [Labeled file uploads](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#labeled-file-uploads) * [Adding multiple personalization questions to a listing](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#adding-multiple-personalization-questions-to-a-listing) * [Updating a listing with existing personalization](https://developers.etsy.com/documentation/tutorials/personalization/multiple-and-new-question-type-support-examples#updating-a-listing-with-existing-personalization) --- # Quick Start Tutorial | Etsy Open API v3 This tutorial walks you through building a very simple Node.js application from start to finish. By the end, you will have a working application with a valid OAuth 2.0 access token to make requests to any scoped endpoint. Initial setup[#](https://developers.etsy.com/documentation/tutorials/quickstart#initial-setup "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------ To get setup, follow these general steps: 1. To begin, you’ll need a development environment with Node.js installed. If you’re unfamiliar with this setup, [follow these official instructions](https://nodejs.org/en/download) . 2. In your environment, create a directory called `etsyapp` and a new file in that directory called `hello.js`: mkdir etsyapp cd etsyapp touch hello.js Copy 3. Write a one line JavaScript program to print a string literal to the console: console.log('Hello, world!'); Copy 4. Save `hello.js` 5. Open a terminal window, navigate to the `etsyapp` directory and type the following command: node hello.js Copy If your node and development environment is set up correctly, the terminal responds with the message "Hello, world!" Get your API key[#](https://developers.etsy.com/documentation/tutorials/quickstart#get-your-api-key "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------ To complete any request to the Etsy Open API v3, you require an Etsy application ID, also know as an API key. Etsy issues API keys upon request to develop an application for your Etsy account. ### Register a new application[#](https://developers.etsy.com/documentation/tutorials/quickstart#register-a-new-application "Direct link to heading") If you don’t have an existing Etsy application, you’ll need to create one. If you have one already, you can skip to the next section. 1. Open a web browser and navigate to [https://www.etsy.com/developers/register](https://www.etsy.com/developers/register) . 2. At a minimum, enter information into the following fields: * _Name_: the name of your app. * _Description_: A description of the app that you can recognize and use to distinguish it from other apps. * _Who will be the users of this application?_ Choose the option that best matches your use case. * _Is your application commercial?_ Select "no". You can change this setting later for a commercial app. 3. Complete the captcha identity verification and click "Read Terms and Create App". ### Find the keystring and shared secret for your application[#](https://developers.etsy.com/documentation/tutorials/quickstart#find-the-keystring-and-shared-secret-for-your-application "Direct link to heading") 1. Navigate to [Manage your apps](https://www.etsy.com/developers/your-apps) on Etsy’s developer page. 2. Click on the plus sign next to "SEE API KEY DETAILS" for the application you want to use in this tutorial. Copy down your Etsy App API Key _keystring_ and _shared secret_. Be sure not to publish the shared secret. ##### Important Your API key is not active until it has been approved. Once approved, the status will be updated under the "See API Key Details" dropdown in the "Manage Your Apps" section. Approval is a prerequisite before continuing with this tutorial. Start with a simple Express server application[#](https://developers.etsy.com/documentation/tutorials/quickstart#start-with-a-simple-express-server-application "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The OAuth2 Authorization Code flow requires a callback URL to which to send the authorization code, which in this case maps to your application. For a server-side app built with Node, this means Node must be running as a server and the callback URL must map to a specific resource on that server. To keep this example simple, we use the Express package for Node and build a basic web service to handle the OAuth2 Authorization Code response. To build a simple web server in Node, perform the following steps: 1. We will be using several npm packages for this tutorial. Start by creating a new file in your `etsyapp` directory called `package.json`. Paste the following code in the file and save it. { "name": "etsyapp", "version": "0.0.1", "description": "A simple Node app that makes requests to Etsy’s Open API.", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": { "express": "4.x", "hbs": "^4.1.2", "node-fetch": "^2.6.1" }, "engines": { "node": ">=12 <15" }, "license": "MIT" } Copy 2. From your terminal, run `npm install`. 3. Create a new file called server.js in your etsyapp directory. For example, you can type the following command in the terminal window and press enter: touch server.js Copy 4. Open `server.js` for editing and write code to start a simple web server on port 3003. For example, if your host URL is localhost: // Import the express library const express \= require('express') // Create a new express application const app \= express(); // Send a "Hello World!" response to a default get request app.get('/', (req, res) \=> { res.send('Hello, world!') }) // Start the server on port 3003 const port \= 3003 app.listen(port, () \=> { console.log(\`Example app listening at http://localhost:${port}\`) }) Copy 5. Save `server.js` 6. Open a terminal window and type the following command: node server.js Copy If you successfully started the web server, your console log should read: Example app listening at http://localhost:3003 Copy And if you open http://localhost:3003 in a web browser on the same machine or any connected machine, you should see the message "Hello, world!" on the web page. Test your API key[#](https://developers.etsy.com/documentation/tutorials/quickstart#test-your-api-key "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------- There are a limited set of Open API v3 endpoints that do not require an OAuth token, so you can test your API key before requesting an access token. Test your API key using the following procedure: 1. Open `server.js` again. 2. Write code to make a GET request to the [`ping`](https://developers.etsy.com/documentation/reference/#operation/ping) endpoint — which does not require authentication scopes — and print the response to the console. For example, if your API _keystring_ were `1aa2bb33c44d55eeeeee6fff` and your shared secret were `a1b2c3d4e5`, then your updated code might look like the following: // Import the express and fetch libraries const express \= require('express'); const fetch \= require("node-fetch"); // Create a new express application const app \= express(); // Send a JSON response to a default get request app.get('/ping', async (req, res) \=> { const requestOptions \= { 'method': 'GET', 'headers': { 'x-api-key': '1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', }, }; const response \= await fetch( 'https://api.etsy.com/v3/application/openapi-ping', requestOptions ); if (response.ok) { const data \= await response.json(); res.send(data); } else { res.send("oops"); } }); // Start the server on port 3003 const port \= 3003; app.listen(port, () \=> { console.log(\`Example app listening at http://localhost:${port}\`); }); Copy 3. Save `server.js` 4. Open a terminal window and type the following command: node server.js Copy Open http://localhost:3003/ping in a web browser on the same machine or any connected machine. If your API _keystring_ and _shared secret_ are working properly, you should see a JSON array that includes the application ID for the application associated with this keystring. The response should look like this: { "application\_id": 1234 } Copy Create the client landing page[#](https://developers.etsy.com/documentation/tutorials/quickstart#create-the-client-landing-page "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------------------------------------- We create an entry point to our application by creating a "views" directory — which Express exposes with middleware — and adding a client landing page that makes an OAuth2 request. To create the client landing page, perform the following procedure: 1. Before you begin, you will need the following authentication parameters: * a redirect URI on your web server, such as http://localhost:3003/oauth/redirect, which you will setup as the '/oauth/redirect' route in the next section * a state string, which can be any non-empty, non-whitespace string, but which you must use in all requests in the same Authorization code flow, for example "superstring" * a PKCE _code challenge_ generated from the _code verifier_, which Etsy requires later in the authorization code flow 2. In your etsyapp directory, create a new directory named "views". 3. Navigate to the `/views` directory and create a new file called "index.hbs". 4. Open index.hbs for editing and code a simple HTML page with an OAuth request. For example, to request an authorization code for an Etsy app requiring an `email_r` scope with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff`, you can create a page with one link like the following: Authenticate with Etsy Copy This link in this template has every element required for an OAuth connect request to Etsy, as detailed in the [Authentication topic](https://developers.etsy.com/documentation/essentials/oauth2) on this site. If you need help generating the state and code challenge values, follow the instructions below. ### Generate the PKCE code challenge[#](https://developers.etsy.com/documentation/tutorials/quickstart#generate-the-pkce-code-challenge "Direct link to heading") There are a variety ways to generate the _state_, _code challenge_, and _code verifier_ values, but we thought it would be helpful to share an example. 1. To start, create a new file called `code-generator.js`. 2. Paste in the following code. const crypto \= require("crypto"); // The next two functions help us generate the code challenge // required by Etsy’s OAuth implementation. const base64URLEncode \= (str) \=> str .toString("base64") .replace(/\\+/g, "-") .replace(/\\//g, "\_") .replace(/\=/g, ""); const sha256 \= (buffer) \=> crypto.createHash("sha256").update(buffer).digest(); // We’ll use the verifier to generate the challenge. // The verifier needs to be saved for a future step in the OAuth flow. const codeVerifier \= base64URLEncode(crypto.randomBytes(32)); // With these functions, we can generate // the values needed for our OAuth authorization grant. const codeChallenge \= base64URLEncode(sha256(codeVerifier)); const state \= Math.random().toString(36).substring(7); console.log(\`State: ${state}\`); console.log(\`Code challenge: ${codeChallenge}\`); console.log(\`Code verifier: ${codeVerifier}\`); console.log(\`Full URL: https://www.etsy.com/oauth/connect?response\_type=code&redirect\_uri=http://localhost:3003/oauth/redirect&scope=email\_r&client\_id=1aa2bb33c44d55eeeeee6fff&state=${state}&code\_challenge=${codeChallenge}&code\_challenge\_method=S256\`) Copy 3. Save the file and run `node code-generator.js` from a terminal prompt. Here’s an example of a successful response in the terminal. State: jqymnj Code challenge: EFJQPpJgc83fWhV5DC2amk-KGi2SYE4xZt5izK-m4a0 Code verifier: U4rzPy5bL6wOPuKFIjvRsCue-9njsek7hTaOymure4o Full URL: https://www.etsy.com/oauth/connect?response\_type=code&redirect\_uri=http://localhost:3003/oauth/redirect&scope=email\_r&client\_id=1aa2bb33c44d55eeeeee6fff&state=jqymnj&code\_challenge=EFJQPpJgc83fWhV5DC2amk-KGi2SYE4xZt5izK-m4a0&code\_challenge\_method=S256 Copy Implement the `redirect_uri` route[#](https://developers.etsy.com/documentation/tutorials/quickstart#implement-the-redirect_uri-route "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------------------------------------------- The URI string for the client landing page above contains a `redirect_uri` "http://localhost:3003/oauth/redirect", which is a local address to which the OAuth server delivers the authorization code. In Node, this `redirect_uri` must be a route to a resource to receive the authentication code and use it to request an OAuth token. Use the following procedure to create the redirect route: 1. Navigate to your /etsyapp directory and open `server.js` in your editor. 2. Add code for the "oauth/redirect" route to make a POST request to `https://api.etsy.com/v3/public/oauth/token` with the authentication code gathered from the request , as shown below: // Import the express and fetch libraries const express \= require('express'); const fetch \= require("node-fetch"); const hbs \= require("hbs"); // Create a new express application const app \= express(); app.set("view engine", "hbs"); app.set("views", \`${process.cwd()}/views\`); // Send a JSON response to a default get request app.get('/ping', async (req, res) \=> { const requestOptions \= { 'method': 'GET', 'headers': { 'x-api-key': '1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', }, }; const response \= await fetch( 'https://api.etsy.com/v3/application/openapi-ping', requestOptions ); if (response.ok) { const data \= await response.json(); res.send(data); } else { res.send("oops"); } }); // This renders our \`index.hbs\` file. app.get('/', async (req, res) \=> { res.render("index"); }); /\*\* These variables contain your API Key, the state sent in the initial authorization request, and the client verifier compliment to the code\_challenge sent with the initial authorization request \*/ const clientID \= ''; const clientVerifier \= ''; const redirectUri \= 'http://localhost:3003/oauth/redirect'; app.get("/oauth/redirect", async (req, res) \=> { // The req.query object has the query params that Etsy authentication sends // to this route. The authorization code is in the \`code\` param const authCode \= req.query.code; const tokenUrl \= 'https://api.etsy.com/v3/public/oauth/token'; const requestOptions \= { method: 'POST', body: JSON.stringify({ grant\_type: 'authorization\_code', client\_id: clientID, redirect\_uri: redirectUri, code: authCode, code\_verifier: clientVerifier, }), headers: { 'Content-Type': 'application/json' } }; const response \= await fetch(tokenUrl, requestOptions); // Extract the access token from the response access\_token data field if (response.ok) { const tokenData \= await response.json(); res.send(tokenData); } else { res.send("oops"); } }); // Start the server on port 3003 const port \= 3003; app.listen(port, () \=> { console.log(\`Example app listening at http://localhost:${port}\`); }); Copy 3. Go back to your terminal prompt and run `node server.js`. Then visit http://localhost:3003. You should see the full JSON payload returned from a successful OAuth flow. ##### tip If you see an error after clicking the “Authenticate with Etsy” button, you might need to [add your redirect URI](https://developers.etsy.com/documentation/essentials/authentication#redirect-uris) . Display a response from a scoped endpoint[#](https://developers.etsy.com/documentation/tutorials/quickstart#display-a-response-from-a-scoped-endpoint "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To finish the tutorial, we will use the generated access token to make an authenticated request to a scoped endpoint. Follow the steps below to create one last route in your Express application. 1. Create a "views/welcome.hbs" file. This template will be used to offer a welcome message to the authenticated user. Copy the following code into the file.

Welcome, {{first\_name}}!

You can now use this example application. 🎉

Copy 2. Write code in our new route handler to request user information from the Open API v3 [getUser](https://developers.etsy.com/documentation/reference/#operation/getUser) endpoint. This requires an access token with `email_r` scope, which was established in the initial authorization code request. For example, this will welcome the authenticated user by their first name: // Import the express and fetch libraries const express \= require('express'); const fetch \= require("node-fetch"); const hbs \= require("hbs"); // Create a new express application const app \= express(); app.set("view engine", "hbs"); app.set("views", \`${process.cwd()}/views\`); // Send a JSON response to a default get request app.get('/ping', async (req, res) \=> { const requestOptions \= { 'method': 'GET', 'headers': { 'x-api-key': '1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', }, }; const response \= await fetch( 'https://api.etsy.com/v3/application/openapi-ping', requestOptions ); if (response.ok) { const data \= await response.json(); res.send(data); } else { res.send("oops"); } }); // This renders our \`index.hbs\` file. app.get('/', async (req, res) \=> { res.render("index"); }); /\*\* These variables contain your API Key, the state sent in the initial authorization request, and the client verifier compliment to the code\_challenge sent with the initial authorization request \*/ const clientID \= ''; const sharedSecret \= ''; const clientVerifier \= ''; const redirectUri \= 'http://localhost:3003/oauth/redirect'; app.get("/oauth/redirect", async (req, res) \=> { // The req.query object has the query params that Etsy authentication sends // to this route. The authorization code is in the \`code\` param const authCode \= req.query.code; const tokenUrl \= 'https://api.etsy.com/v3/public/oauth/token'; const requestOptions \= { method: 'POST', body: JSON.stringify({ grant\_type: 'authorization\_code', client\_id: clientID, redirect\_uri: redirectUri, code: authCode, code\_verifier: clientVerifier, }), headers: { 'Content-Type': 'application/json' } }; // Extract the access token from the response access\_token data field if (response.ok) { const tokenData \= await response.json(); res.redirect(\`/welcome?access\_token=${tokenData.access\_token}\`); } else { res.send("oops"); } }); app.get("/welcome", async (req, res) \=> { // We passed the access token in via the querystring const { access\_token } \= req.query; // An Etsy access token includes your shop/user ID // as a token prefix, so we can extract that too const user\_id \= access\_token.split('.')\[0\]; const requestOptions \= { headers: { 'x-api-key': \`${clientID}:${sharedSecret}\`, // Scoped endpoints require a bearer token Authorization: \`Bearer ${access\_token}\`, } }; const response \= await fetch( \`https://api.etsy.com/v3/application/users/${user\_id}\`, requestOptions ); if (response.ok) { const userData \= await response.json(); // Load the template with the first name as a template variable. res.render("welcome", { first\_name: userData.first\_name }); } else { res.send("oops"); } }); // Start the server on port 3003 const port \= 3003; app.listen(port, () \=> { console.log(\`Example app listening at http://localhost:${port}\`); }); Copy 3. Go back to your terminal prompt and run `node server.js`. Then visit http://localhost:3003. If the `code_challenge` value in your index.hbs file is still valid, you should be able to go through the authentication flow and find yourself at the `/welcome` page with the following message: Welcome, ! You can now use this example application. 🎉 Copy Handling errors[#](https://developers.etsy.com/documentation/tutorials/quickstart#handling-errors "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------- While thorough error handling is out of scope for this tutorial, here is a simple way to see more of the error response with `fetch`. When `response.ok` returns `false`, you can access the error response with the following code: if (response.ok) { const data \= await response.json(); res.send(data); } else { // Log http status to the console console.log(response.status, response.statusText); // For non-500 errors, the endpoints return a JSON object as an error response const errorData \= await response.json(); console.log(errorData); res.send("oops"); } Copy If you followed every step of this tutorial, you likely ran into an error when implementing the welcome page as your code value had been used before. If you implement the error handling above, `errorData` would log the following value: { error: 'invalid\_grant', error\_description: 'code has been used previously' } Copy Wrap up[#](https://developers.etsy.com/documentation/tutorials/quickstart#wrap-up "Direct link to heading") ------------------------------------------------------------------------------------------------------------ That’s where we will wrap up our quickstart guide. Here are a few places you could turn next: * [Requesting a Refresh OAuth Token](https://developers.etsy.com/documentation/essentials/authentication#requesting-a-refresh-oauth-token) * [API Reference](https://developers.etsy.com/documentation/reference) * Explore one of our [other tutorials](https://developers.etsy.com/documentation/tutorials/overview) * [Initial setup](https://developers.etsy.com/documentation/tutorials/quickstart#initial-setup) * [Get your API key](https://developers.etsy.com/documentation/tutorials/quickstart#get-your-api-key) * [Register a new application](https://developers.etsy.com/documentation/tutorials/quickstart#register-a-new-application) * [Find the keystring and shared secret for your application](https://developers.etsy.com/documentation/tutorials/quickstart#find-the-keystring-and-shared-secret-for-your-application) * [Start with a simple Express server application](https://developers.etsy.com/documentation/tutorials/quickstart#start-with-a-simple-express-server-application) * [Test your API key](https://developers.etsy.com/documentation/tutorials/quickstart#test-your-api-key) * [Create the client landing page](https://developers.etsy.com/documentation/tutorials/quickstart#create-the-client-landing-page) * [Generate the PKCE code challenge](https://developers.etsy.com/documentation/tutorials/quickstart#generate-the-pkce-code-challenge) * [Implement the `redirect_uri` route](https://developers.etsy.com/documentation/tutorials/quickstart#implement-the-redirect_uri-route) * [Display a response from a scoped endpoint](https://developers.etsy.com/documentation/tutorials/quickstart#display-a-response-from-a-scoped-endpoint) * [Handling errors](https://developers.etsy.com/documentation/tutorials/quickstart#handling-errors) * [Wrap up](https://developers.etsy.com/documentation/tutorials/quickstart#wrap-up) --- # Etsy Open API v3 | Etsy Open API v3 Welcome to the improved Etsy Open API v3, a REST API that extends support for inventory, sales orders, and shop management on the Etsy platform. These guides support current and future app developers as they build tools to integrate with and automate processes for Etsy shops and customers. Getting started[#](https://developers.etsy.com/documentation#getting-started "Direct link to heading") ------------------------------------------------------------------------------------------------------- Our updated documentation is divided into a few sections, geared towards different use cases. * [Quick Start Guide](https://developers.etsy.com/documentation/tutorials/quickstart) * [API reference](https://developers.etsy.com/documentation/reference) * [API essentials](https://developers.etsy.com/documentation/essentials/oauth2/) * [Tutorials](https://developers.etsy.com/documentation/tutorials/overview) Developing a New Open API App[#](https://developers.etsy.com/documentation#developing-a-new-open-api-app "Direct link to heading") ----------------------------------------------------------------------------------------------------------------------------------- To develop a new application using Etsy's Open API v3, [register your app with Etsy](https://www.etsy.com/developers/register) . Registration generates an Etsy App API Key _keystring_ and a _shared secret_, which you can find in [Your Apps](https://www.etsy.com/developers/your-apps) and allows you to use v3 Open API endpoints. Registered apps begin with [personal access](https://developers.etsy.com/documentation#personal-access) to our production systems. An application that has not made a succesful request to Etsy's OpenAPI service in 6 months will be marked as _dormant_ and banned. ### Personal Access[#](https://developers.etsy.com/documentation#personal-access "Direct link to heading") By default, all new applications support personal access, which is authenticated read/write access to a shop granted by the owner and controlled by [Oauth token scopes](https://developers.etsy.com/documentation/essentials/oauth2#scopes) . This supports designing access controls for different application users into the app, such as reading data on receipts and billing or creating, editing, and deleting your shop's listings. Personal access is permitted to connect with up to 5 shops. ### Commercial Access[#](https://developers.etsy.com/documentation#commercial-access "Direct link to heading") General-purpose applications that can assist any seller manage their shop, not just your shop, require commercial access. To request commercial access, click the "Request Commercial Access" link next to your app in [Apps You've Made](https://www.etsy.com/developers/your-apps) . ##### important If you're only accessing data from your own shop, you do not need commercial access. To implement Oauth authentication to protect access to your shop, see [Authentication](https://developers.etsy.com/documentation/essentials/oauth2) . Etsy reviews requests for commercial access against the following criteria: 1. Applications and their home pages must comply with our [API Terms of Use](https://www.etsy.com/legal/api) . 2. Applications must follow the caching policies identified in [Section 1](https://www.etsy.com/legal/api#license) of the API Terms of Use. 3. Applications must clearly distinguish themselves from Etsy, as noted in [Section 6](https://www.etsy.com/legal/api#marks) of the API Terms of Use. Particularly, the following phrase must appear in a prominent position in your application: **"The term 'Etsy' is a trademark of Etsy, Inc. This application uses the Etsy API but is not endorsed or certified by Etsy, Inc."** 4. Applications must not sidestep the API to retrieve or post Etsy data. Screen-scraping is not allowed. 5. Applications that access private member data must use OAuth authentication to do so. 6. Application names and artwork, including icons and home pages, must follow our [Trademark Policy](https://www.etsy.com/help/article/481) . 7. Applications with commercial access that use the `transaction_r` permission scope must request access to the `buyer_email` field separately. Etsy approves these requests on a case by case basis. Get Help[#](https://developers.etsy.com/documentation#get-help "Direct link to heading") ----------------------------------------------------------------------------------------- When you need more support, please refer to the resources on our [help page](https://developers.etsy.com/documentation/get-help) . * [Getting started](https://developers.etsy.com/documentation#getting-started) * [Developing a New Open API App](https://developers.etsy.com/documentation#developing-a-new-open-api-app) * [Personal Access](https://developers.etsy.com/documentation#personal-access) * [Commercial Access](https://developers.etsy.com/documentation#commercial-access) * [Get Help](https://developers.etsy.com/documentation#get-help) --- # Reference | Etsy Open API v3 * Authentication * Listing Management * BuyerTaxonomy * getgetBuyerTaxonomyNodes * getgetPropertiesByBuyerTaxonomyId * SellerTaxonomy * getgetSellerTaxonomyNodes * getgetPropertiesByTaxonomyId * ShopListing * postcreateDraftListing * getgetListingsByShop * deldeleteListing * getgetListing * getfindAllListingsActive * getfindAllActiveListingsByShop * getgetListingsByListingIds * getgetFeaturedListingsByShop * deldeleteListingProperty * putupdateListingProperty * getgetListingProperty * getgetListingProperties * patchupdateListing * getgetListingsByShopReceipt * getgetListingsByShopReturnPolicy * getgetListingsByShopSectionId * ShopListing File * deldeleteListingFile * getgetListingFile * getgetAllListingFiles * postuploadListingFile * ShopListing Image * deldeleteListingImage * getgetListingImage * getgetListingImages * postuploadListingImage * ShopListing Inventory * getgetListingInventory * putupdateListingInventory * ShopListing Offering * getgetListingOffering * ShopListing Personalization * deldeleteListingPersonalization * postupdateListingPersonalization * getgetListingPersonalization * ShopListing Product * getgetListingProduct * ShopListing Translation * postcreateListingTranslation * getgetListingTranslation * putupdateListingTranslation * ShopListing VariationImage * getgetListingVariationImages * postupdateVariationImages * ShopListing Video * deldeleteListingVideo * getgetListingVideo * getgetListingVideos * postuploadListingVideo * Other * Other * getping * posttokenScopes * Payment Management * Ledger Entry * getgetShopPaymentAccountLedgerEntry * getgetShopPaymentAccountLedgerEntries * Payment * getgetPaymentAccountLedgerEntryPayments * getgetShopPaymentByReceiptId * getgetPayments * Receipt Management * Shop Receipt * getgetShopReceipt * putupdateShopReceipt * getgetShopReceipts * postcreateReceiptShipment * Shop Receipt Transactions * getgetShopReceiptTransactionsByListing * getgetShopReceiptTransactionsByReceipt * getgetShopReceiptTransaction * getgetShopReceiptTransactionsByShop * Review Management * Review * getgetReviewsByListing * getgetReviewsByShop * Shipping Management * Shop HolidayPreferences * getgetHolidayPreferences * putupdateHolidayPreferences * Shop ProcessingProfiles * postcreateShopReadinessStateDefinition * getgetShopReadinessStateDefinitions * deldeleteShopReadinessStateDefinition * getgetShopReadinessStateDefinition * putupdateShopReadinessStateDefinition * Shop ShippingProfile * getgetShippingCarriers * postcreateShopShippingProfile * getgetShopShippingProfiles * deldeleteShopShippingProfile * getgetShopShippingProfile * putupdateShopShippingProfile * postcreateShopShippingProfileDestination * getgetShopShippingProfileDestinationsByShippingProfile * deldeleteShopShippingProfileDestination * putupdateShopShippingProfileDestination * postcreateShopShippingProfileUpgrade * getgetShopShippingProfileUpgrades * deldeleteShopShippingProfileUpgrade * putupdateShopShippingProfileUpgrade * Shop Management * Shop * getgetShop * putupdateShop * getgetShopByOwnerUserId * getfindShops * Shop ProductionPartner * getgetShopProductionPartners * Shop Section * postcreateShopSection * getgetShopSections * deldeleteShopSection * getgetShopSection * putupdateShopSection * Shop Policy Management * Shop Return Policy * postconsolidateShopReturnPolicies * postcreateShopReturnPolicy * getgetShopReturnPolicies * deldeleteShopReturnPolicy * getgetShopReturnPolicy * putupdateShopReturnPolicy * User Management * User * getgetUser * getgetMe * UserAddress * deldeleteUserAddress * getgetUserAddress * getgetUserAddresses [Documentation Powered by ReDoc](https://github.com/Redocly/redoc) Etsy Open API v3 (3.0.0) ======================== Download OpenAPI specification:[Download](https://www.etsy.com/openapi/generated/oas/3.0.0.json) E-mail: [developers@etsy.com](mailto:developers@etsy.com) [Terms of Service](https://www.etsy.com/legal/api) Etsy's Open API provides a simple RESTful interface for various Etsy.com features. If you'd like to report an issue or provide feedback on the API design, [please add an issue in Github](https://github.com/etsy/open-api/discussions) . © 2021-2026 Etsy, Inc. All Rights Reserved. Use of this code is subject to Etsy's [API Developer Terms of Use](https://www.etsy.com/legal/api) . [](https://developers.etsy.com/documentation/reference#section/Authentication) Authentication ============================================================================================= [](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) api\_key ----------------------------------------------------------------------------------------------- Every request to a v3 API endpoint must include this data in the format `keystring:shared_secret`. Your keystring and shared secret are available on the [Your Apps](https://www.etsy.com/developers/your-apps) page. | | | | --- | --- | | Security Scheme Type | API Key | | Header parameter name: | x-api-key | [](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) oauth2 -------------------------------------------------------------------------------------------- Open API v3 supports authenticating via OAuth 2.0. More information about Etsy's specific implementation of OAuth2 can be found [here](https://developers.etsy.com/documentation/essentials/oauth2) . | | | | --- | --- | | Security Scheme Type | OAuth2 | | authorizationCode OAuth Flow | **Authorization URL:** https://www.etsy.com/oauth/connect

**Token URL:** https://openapi.etsy.com/v3/public/oauth/token

**Scopes:**

* `address_r` -

see billing and shipping addresses

* `address_w` -

update billing and shipping addresses

* `billing_r` -

see all billing statement data

* `cart_r` -

read shopping carts

* `cart_w` -

add/remove from shopping carts

* `email_r` -

read a user profile

* `favorites_r` -

see private favorites

* `favorites_w` -

add/remove favorites

* `feedback_r` -

see purchase info in feedback

* `listings_d` -

delete listings

* `listings_r` -

see all listings (including expired etc)

* `listings_w` -

create/edit listings

* `profile_r` -

see all profile data

* `profile_w` -

update user profile, avatar, etc

* `recommend_r` -

see recommended listings

* `recommend_w` -

accept/reject recommended listings

* `shops_r` -

see private shop info

* `shops_w` -

update shop

* `transactions_r` -

see all checkout/payment data

* `transactions_w` -

update receipts | [](https://developers.etsy.com/documentation/reference#tag/BuyerTaxonomy) BuyerTaxonomy ======================================================================================= [](https://developers.etsy.com/documentation/reference#operation/getBuyerTaxonomyNodes) getBuyerTaxonomyNodes ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the full hierarchy tree of buyer taxonomy nodes. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ### Responses **200** List the full hierarchy tree of buyer taxonomy nodes. **500** The server encountered an internal error. See the error message for details. get/v3/application/buyer-taxonomy/nodes Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/buyer-taxonomy/nodes ### Response samples * 200 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "id": 1, * "level": 0, * "name": "string", * "parent_id": null, * "children": [ * { } ], * "full_path_taxonomy_ids": [ * 1 ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/getPropertiesByBuyerTaxonomyId) getPropertiesByBuyerTaxonomyId ------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of product properties, with applicable scales and values, supported for a specific buyer taxonomy ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | taxonomy\_id

required | integer \>= 1

The unique numeric ID of an Etsy taxonomy node, which is a metadata category for listings organized into the seller taxonomy hierarchy tree. For example, the "shoes" taxonomy node (ID: 1429, level: 1) is higher in the hierarchy than "girls' shoes" (ID: 1440, level: 2). The taxonomy nodes assigned to a listing support access to specific standardized product scales and properties. For example, listings assigned the taxonomy nodes "shoes" or "girls' shoes" support access to the "EU" shoe size scale with its associated property names and IDs for EU shoe sizes, such as property `value_id`:"1394", and `name`:"38". | ### Responses **200** A list of product properties, with applicable scales and values. **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/buyer-taxonomy/nodes/{taxonomy\_id}/properties Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/buyer-taxonomy/nodes/{taxonomy\_id}/properties ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "property_id": 1, * "name": "string", * "display_name": "string", * "scales": [ * { * "scale_id": 1, * "display_name": "string", * "description": "string" } ], * "is_required": true, * "supports_attributes": true, * "supports_variations": true, * "is_multivalued": true, * "max_values_allowed": 0, * "possible_values": [ * { * "value_id": 1, * "name": "string", * "scale_id": 1, * "equal_to": [ * 0 ] } ], * "selected_values": [ * { * "value_id": 1, * "name": "string", * "scale_id": 1, * "equal_to": [ * 0 ] } ] } ] }` [](https://developers.etsy.com/documentation/reference#tag/SellerTaxonomy) SellerTaxonomy ========================================================================================= [](https://developers.etsy.com/documentation/reference#operation/getSellerTaxonomyNodes) getSellerTaxonomyNodes --------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the full hierarchy tree of seller taxonomy nodes. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ### Responses **200** List the full hierarchy tree of seller taxonomy nodes. **500** The server encountered an internal error. See the error message for details. **503** The service is unavailable get/v3/application/seller-taxonomy/nodes Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/seller-taxonomy/nodes ### Response samples * 200 * 500 * 503 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "id": 1, * "level": 0, * "name": "string", * "parent_id": null, * "children": [ * { } ], * "full_path_taxonomy_ids": [ * 1 ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/getPropertiesByTaxonomyId) getPropertiesByTaxonomyId --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of product properties, with applicable scales and values, supported for a specific seller taxonomy ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | taxonomy\_id

required | integer \>= 1

The unique numeric ID of an Etsy taxonomy node, which is a metadata category for listings organized into the seller taxonomy hierarchy tree. For example, the "shoes" taxonomy node (ID: 1429, level: 1) is higher in the hierarchy than "girls' shoes" (ID: 1440, level: 2). The taxonomy nodes assigned to a listing support access to specific standardized product scales and properties. For example, listings assigned the taxonomy nodes "shoes" or "girls' shoes" support access to the "EU" shoe size scale with its associated property names and IDs for EU shoe sizes, such as property `value_id`:"1394", and `name`:"38". | ### Responses **200** A list of product properties, with applicable scales and values. **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/seller-taxonomy/nodes/{taxonomy\_id}/properties Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/seller-taxonomy/nodes/{taxonomy\_id}/properties ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "property_id": 1, * "name": "string", * "display_name": "string", * "scales": [ * { * "scale_id": 1, * "display_name": "string", * "description": "string" } ], * "is_required": true, * "supports_attributes": true, * "supports_variations": true, * "is_multivalued": true, * "max_values_allowed": 0, * "possible_values": [ * { * "value_id": 1, * "name": "string", * "scale_id": 1, * "equal_to": [ * 0 ] } ], * "selected_values": [ * { * "value_id": 1, * "name": "string", * "scale_id": 1, * "equal_to": [ * 0 ] } ] } ] }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing) ShopListing =================================================================================== [](https://developers.etsy.com/documentation/reference#operation/createDraftListing) createDraftListing ------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates a physical draft [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing) product in a shop on the Etsy channel. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | quantity

required | integer

The positive non-zero number of products available for purchase in the listing. Note: The listing quantity is the sum of available offering quantities. You can request the quantities for individual offerings from the ListingInventory resource using the [getListingInventory](https://developers.etsy.com/documentation/reference#operation/getListingInventory)
endpoint. | | title

required | string

The listing's title string. When creating or updating a listing, valid title strings contain only letters, numbers, punctuation marks, mathematical symbols, whitespace characters, ™, ©, and ®. (regex: /\[^\\p{L}\\p{Nd}\\p{P}\\p{Sm}\\p{Zs}™©®\]/u) You can only use the %, :, & and + characters once each. | | description

required | string

A description string of the product for sale in the listing. | | price

required | number

The positive non-zero price of the product. (Sold product listings are private) Note: The price is the minimum possible price. The [`getListingInventory`](https://developers.etsy.com/documentation/reference/#operation/getListingInventory)
method requests exact prices for available offerings. | | who\_made

required | string

Enum: "i\_did" "someone\_else" "collective"

An enumerated string indicating who made the product. Helps buyers locate the listing under the Handmade heading. Requires 'is\_supply' and 'when\_made'. | | when\_made

required | string

Enum: "made\_to\_order" "2020\_2026" "2010\_2019" "2007\_2009" "before\_2007" "2000\_2006" "1990s" "1980s" "1970s" "1960s" "1950s" "1940s" "1930s" "1920s" "1910s" "1900s" "1800s" "1700s" "before\_1700"

An enumerated string for the era in which the maker made the product in this listing. Helps buyers locate the listing under the Vintage heading. Requires 'is\_supply' and 'who\_made'. | | taxonomy\_id

required | integer \>= 1

The numerical taxonomy ID of the listing. See [SellerTaxonomy](https://developers.etsy.com/documentation/reference#tag/SellerTaxonomy)
and [BuyerTaxonomy](https://developers.etsy.com/documentation/reference#tag/BuyerTaxonomy)
for more information. | | shipping\_profile\_id | integer \>= 1 Nullable

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | | return\_policy\_id | integer \>= 1 Nullable

The numeric ID of the [Return Policy](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies)
. | | materials | Array of strings Nullable

A list of material strings for materials used in the product. Valid materials strings contain only letters, numbers, and whitespace characters. (regex: /\[^\\p{L}\\p{Nd}\\p{Zs}\]/u) Default value is null. | | shop\_section\_id | integer \>= 1 Nullable

The numeric ID of the [shop section](https://developers.etsy.com/documentation/reference#tag/Shop-Section)
for this listing. Default value is null. | | processing\_min | integer Nullable

The minimum number of days required to process this listing. Default value is null. | | processing\_max | integer Nullable

The maximum number of days required to process this listing. Default value is null. | | readiness\_state\_id | integer \>= 1 Nullable

The numeric ID of the [processing profile](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinition)
associated with the listing. Returned only when the listing is `active` and of type `physical`, and the endpoint is either shop-scoped (path contains `shop_id`) or a single-listing request such as `getListing`. For every other case this field can be null. | | tags | Array of strings Nullable

A comma-separated list of tag strings for the listing. When creating or updating a listing, valid tag strings contain only letters, numbers, whitespace characters, -, ', ™, ©, and ®. (regex: /\[^\\p{L}\\p{Nd}\\p{Zs}-'™©®\]/u) Default value is null. | | styles | Array of strings Nullable

An array of style strings for this listing, each of which is free-form text string such as "Formal", or "Steampunk". When creating or updating a listing, the listing may have up to two styles. Valid style strings contain only letters, numbers, and whitespace characters. (regex: /\[^\\p{L}\\p{Nd}\\p{Zs}\]/u) Default value is null. | | item\_weight | number \[ 0 .. 1.79769313486e+308 \] Nullable

The numeric weight of the product measured in units set in 'item\_weight\_unit'. Default value is null. If set, the value must be greater than 0. | | item\_length | number \[ 0 .. 1.79769313486e+308 \] Nullable

The numeric length of the product measured in units set in 'item\_dimensions\_unit'. Default value is null. If set, the value must be greater than 0. | | item\_width | number \[ 0 .. 1.79769313486e+308 \] Nullable

The numeric width of the product measured in units set in 'item\_dimensions\_unit'. Default value is null. If set, the value must be greater than 0. | | item\_height | number \[ 0 .. 1.79769313486e+308 \] Nullable

The numeric height of the product measured in units set in 'item\_dimensions\_unit'. Default value is null. If set, the value must be greater than 0. | | item\_weight\_unit | string Nullable

Enum: "oz" "lb" "g" "kg"

A string defining the units used to measure the weight of the product. Default value is null. | | item\_dimensions\_unit | string Nullable

Enum: "in" "ft" "mm" "cm" "m" "yd" "inches"

A string defining the units used to measure the dimensions of the product. Default value is null. | | is\_personalizable | boolean

When true, this listing is personalizable. The default value is false. | | personalization\_is\_required | boolean

\[DEPRECATED\] When true, this listing requires personalization. The default value is false. NOTE: This field will be removed on Apr. 9th, 2026. See [https://developers.etsy.com/documentation/tutorials/personalization-migration](https://developers.etsy.com/documentation/tutorials/personalization-migration)
for migration details. | | personalization\_char\_count\_max | integer

\[DEPRECATED\] This is an integer value representing the maximum length for the personalization message entered by the buyer. Will only change if is\_personalizable is 'true'. Note: This field will be removed on Apr. 9th, 2026. See [https://developers.etsy.com/documentation/tutorials/personalization-migration](https://developers.etsy.com/documentation/tutorials/personalization-migration)
for migration details. | | personalization\_instructions | string

\[DEPRECATED\] A string representing instructions for the buyer to enter the personalization. Will only change if is\_personalizable is 'true'. Note: This field will be removed on Apr. 9th, 2026. See [https://developers.etsy.com/documentation/tutorials/personalization-migration](https://developers.etsy.com/documentation/tutorials/personalization-migration)
for migration details. | | production\_partner\_ids | Array of integers Nullable

An array of unique IDs of production partner ids. | | image\_ids | Array of integers Nullable

An array of numeric image IDs of the images in a listing, which can include up to 20 images. | | is\_supply | boolean

When true, tags the listing as a supply product, else indicates that it's a finished product. Helps buyers locate the listing under the Supplies heading. Requires 'who\_made' and 'when\_made'. | | is\_customizable | boolean

When true, a buyer may contact the seller for a customized order. The default value is true when a shop accepts custom orders. Does not apply to shops that do not accept custom orders. | | should\_auto\_renew | boolean

When true, renews a listing for four months upon expiration. | | is\_taxable | boolean

When true, applicable [shop](https://developers.etsy.com/documentation/reference#tag/Shop)
tax rates apply to this listing at checkout. | | type | string

Enum: "physical" "download" "both"

An enumerated type string that indicates whether the listing is physical or a digital download. | ### Responses **201** A single ShopListing **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/listings Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings ### Response samples * 201 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getListingsByShop) getListingsByShop ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Endpoint to list Listings that belong to a Shop. Listings can be filtered using the 'state' param. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | state | string

Default: "active"

Enum: "active" "inactive" "sold\_out" "draft" "expired"

When _updating_ a listing, this value can be either `active` or `inactive`. Note: Setting a `draft` listing to `active` will also publish the listing on etsy.com and requires that the listing have an image set. Setting a `sold_out` listing to active will update the quantity to 1 and renew the listing on etsy.com. | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | sort\_on | string

Default: "created"

Enum: "created" "price" "updated" "score"

The value to sort a search result of listings on. NOTES: a) `sort_on` only works when combined with one of the search options (keywords, region, etc.). b) when using `score` the returned results will always be in _descending_ order, regardless of the `sort_order` parameter. | | sort\_order | string

Default: "desc"

Enum: "asc" "ascending" "desc" "descending" "up" "down"

The ascending(up) or descending(down) order to sort listings by. NOTE: sort\_order only works when combined with one of the search options (keywords, region, etc.). | | includes | Array of strings

Default: null

Items Enum: "Shipping" "Images" "Shop" "User" "Translations" "Inventory" "Videos" "Personalization"

An enumerated string that attaches a valid association. Acceptable inputs are 'Shipping', 'Shop', 'Images', 'User', 'Translations', 'Videos', 'Inventory' and 'Personalization'. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of Listings **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings ### Response samples * 200 * 400 * 401 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string", * "shipping_profile": { * "shipping_profile_id": 1, * "title": "string", * "user_id": 1, * "origin_country_iso": "string", * "is_deleted": true, * "shipping_profile_destinations": [ * { * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "shipping_profile_upgrades": [ * { * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "origin_postal_code": "string", * "profile_type": "manual", * "domestic_handling_fee": 0, * "international_handling_fee": 0 }, * "user": { * "user_id": 1, * "primary_email": "user@example.com", * "first_name": "string", * "last_name": "string", * "image_url_75x75": "string" }, * "shop": { * "shop_id": 1, * "user_id": 1, * "shop_name": "string", * "create_date": 0, * "created_timestamp": 0, * "title": "string", * "announcement": "string", * "currency_code": "string", * "is_vacation": true, * "vacation_message": "string", * "sale_message": "string", * "digital_sale_message": "string", * "update_date": 0, * "updated_timestamp": 0, * "listing_active_count": 0, * "digital_listing_count": 0, * "login_name": "string", * "accepts_custom_requests": true, * "policy_welcome": "string", * "policy_payment": "string", * "policy_shipping": "string", * "policy_refunds": "string", * "policy_additional": "string", * "policy_seller_info": "string", * "policy_update_date": 0, * "policy_has_private_receipt_info": true, * "has_unstructured_policies": true, * "policy_privacy": "string", * "vacation_autoreply": "string", * "url": "string", * "image_url_760x100": "string", * "num_favorers": 0, * "languages": [ * "string" ], * "icon_url_fullxfull": "string", * "is_using_structured_policies": true, * "has_onboarded_structured_policies": true, * "include_dispute_form_link": true, * "is_direct_checkout_onboarded": true, * "is_etsy_payments_onboarded": true, * "is_calculated_eligible": true, * "is_opted_in_to_buyer_promise": true, * "is_shop_us_based": true, * "transaction_sold_count": 0, * "shipping_from_country_iso": "string", * "shop_location_country_iso": "string", * "review_count": 0, * "review_average": 0 }, * "images": [ * { * "listing_id": 1, * "listing_image_id": 1, * "hex_code": "string", * "red": 0, * "green": 0, * "blue": 0, * "hue": 0, * "saturation": 0, * "brightness": 0, * "is_black_and_white": true, * "creation_tsz": 0, * "created_timestamp": 0, * "rank": 0, * "url_75x75": "string", * "url_170x135": "string", * "url_570xN": "string", * "url_fullxfull": "string", * "full_height": 0, * "full_width": 0, * "alt_text": "string" } ], * "videos": [ * { * "video_id": 1, * "height": 0, * "width": 0, * "thumbnail_url": "string", * "video_url": "string", * "video_state": "active" } ], * "inventory": { * "products": [ * { * "product_id": 1, * "sku": "string", * "is_deleted": true, * "offerings": [ * { * "offering_id": 1, * "quantity": 0, * "is_enabled": true, * "is_deleted": true, * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "readiness_state_id": 1 } ], * "property_values": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ] } ], * "price_on_property": [ * 0 ], * "quantity_on_property": [ * 0 ], * "sku_on_property": [ * 0 ], * "readiness_state_on_property": [ * 1 ] }, * "production_partners": [ * { * "production_partner_id": 1, * "partner_name": "string", * "location": "string" } ], * "skus": [ * "string" ], * "translations": { * "de": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-GB": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-IN": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-US": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "es": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "fr": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "it": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "ja": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "nl": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "pl": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "pt": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "ru": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "sv": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] } }, * "views": 0, * "personalization": { * "personalization_questions": [ * { * "question_id": 1, * "question_text": "string", * "instructions": "string", * "question_type": "string", * "required": true, * "max_allowed_characters": 0, * "max_allowed_files": 0, * "options": [ * { * "option_id": 1, * "label": "string" } ] } ] } } ] }` [](https://developers.etsy.com/documentation/reference#operation/deleteListing) deleteListing --------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 endpoint to delete a ShopListing. A ShopListing can be deleted only if the state is one of the following: SOLD\_OUT, DRAFT, EXPIRED, INACTIVE, ACTIVE and is\_available or ACTIVE and has seller flags: SUPRESSED (frozen), VACATION, CUSTOM\_SHOPS (pattern), SELL\_ON\_FACEBOOK ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_d`) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ### Responses **204** The Listing resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/listings/{listing\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id} ### Response samples * 400 * 401 * 403 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getListing) getListing --------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a listing record by listing ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | includes | Array of strings

Default: null

Items Enum: "Shipping" "Images" "Shop" "User" "Translations" "Inventory" "Videos" "Personalization"

An enumerated string that attaches a valid association. Acceptable inputs are 'Shipping', 'Shop', 'Images', 'User', 'Translations', 'Videos', 'Inventory' and 'Personalization'. | | language | string

Default: null

The IETF language tag for the language of this translation. Ex: `de`, `en`, `es`, `fr`, `it`, `ja`, `nl`, `pl`, `pt`. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | | allow\_suggested\_title | boolean

This parameter will include in the response a suggested title for the listing, if one is available. Since suggestions are only available to the listing's owner, client must submit an oauth\_access\_token scoped to the owner of the listing. | ### Responses **200** A single Listing. **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id} ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string", * "shipping_profile": { * "shipping_profile_id": 1, * "title": "string", * "user_id": 1, * "origin_country_iso": "string", * "is_deleted": true, * "shipping_profile_destinations": [ * { * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "shipping_profile_upgrades": [ * { * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "origin_postal_code": "string", * "profile_type": "manual", * "domestic_handling_fee": 0, * "international_handling_fee": 0 }, * "user": { * "user_id": 1, * "primary_email": "user@example.com", * "first_name": "string", * "last_name": "string", * "image_url_75x75": "string" }, * "shop": { * "shop_id": 1, * "user_id": 1, * "shop_name": "string", * "create_date": 0, * "created_timestamp": 0, * "title": "string", * "announcement": "string", * "currency_code": "string", * "is_vacation": true, * "vacation_message": "string", * "sale_message": "string", * "digital_sale_message": "string", * "update_date": 0, * "updated_timestamp": 0, * "listing_active_count": 0, * "digital_listing_count": 0, * "login_name": "string", * "accepts_custom_requests": true, * "policy_welcome": "string", * "policy_payment": "string", * "policy_shipping": "string", * "policy_refunds": "string", * "policy_additional": "string", * "policy_seller_info": "string", * "policy_update_date": 0, * "policy_has_private_receipt_info": true, * "has_unstructured_policies": true, * "policy_privacy": "string", * "vacation_autoreply": "string", * "url": "string", * "image_url_760x100": "string", * "num_favorers": 0, * "languages": [ * "string" ], * "icon_url_fullxfull": "string", * "is_using_structured_policies": true, * "has_onboarded_structured_policies": true, * "include_dispute_form_link": true, * "is_direct_checkout_onboarded": true, * "is_etsy_payments_onboarded": true, * "is_calculated_eligible": true, * "is_opted_in_to_buyer_promise": true, * "is_shop_us_based": true, * "transaction_sold_count": 0, * "shipping_from_country_iso": "string", * "shop_location_country_iso": "string", * "review_count": 0, * "review_average": 0 }, * "images": [ * { * "listing_id": 1, * "listing_image_id": 1, * "hex_code": "string", * "red": 0, * "green": 0, * "blue": 0, * "hue": 0, * "saturation": 0, * "brightness": 0, * "is_black_and_white": true, * "creation_tsz": 0, * "created_timestamp": 0, * "rank": 0, * "url_75x75": "string", * "url_170x135": "string", * "url_570xN": "string", * "url_fullxfull": "string", * "full_height": 0, * "full_width": 0, * "alt_text": "string" } ], * "videos": [ * { * "video_id": 1, * "height": 0, * "width": 0, * "thumbnail_url": "string", * "video_url": "string", * "video_state": "active" } ], * "inventory": { * "products": [ * { * "product_id": 1, * "sku": "string", * "is_deleted": true, * "offerings": [ * { * "offering_id": 1, * "quantity": 0, * "is_enabled": true, * "is_deleted": true, * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "readiness_state_id": 1 } ], * "property_values": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ] } ], * "price_on_property": [ * 0 ], * "quantity_on_property": [ * 0 ], * "sku_on_property": [ * 0 ], * "readiness_state_on_property": [ * 1 ] }, * "production_partners": [ * { * "production_partner_id": 1, * "partner_name": "string", * "location": "string" } ], * "skus": [ * "string" ], * "translations": { * "de": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-GB": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-IN": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-US": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "es": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "fr": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "it": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "ja": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "nl": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "pl": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "pt": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "ru": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "sv": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] } }, * "views": 0, * "personalization": { * "personalization_questions": [ * { * "question_id": 1, * "question_text": "string", * "instructions": "string", * "question_type": "string", * "required": true, * "max_allowed_characters": 0, * "max_allowed_files": 0, * "options": [ * { * "option_id": 1, * "label": "string" } ] } ] } }` [](https://developers.etsy.com/documentation/reference#operation/findAllListingsActive) findAllListingsActive ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. A list of all active listings on Etsy paginated by their creation date. Without sort\_order listings will be returned newest-first by default. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | keywords | string

Default: null

Search term or phrase that must appear in all results. | | sort\_on | string

Default: "created"

Enum: "created" "price" "updated" "score"

The value to sort a search result of listings on. NOTES: a) `sort_on` only works when combined with one of the search options (keywords, region, etc.). b) when using `score` the returned results will always be in _descending_ order, regardless of the `sort_order` parameter. | | sort\_order | string

Default: "desc"

Enum: "asc" "ascending" "desc" "descending" "up" "down"

The ascending(up) or descending(down) order to sort listings by. NOTE: sort\_order only works when combined with one of the search options (keywords, region, etc.). | | min\_price | number

Default: null

The minimum price of listings to be returned by a search result. | | max\_price | number

Default: null

The maximum price of listings to be returned by a search result. | | taxonomy\_id | integer \>= 1

Default: null

The numerical taxonomy ID of the listing. See [SellerTaxonomy](https://developers.etsy.com/documentation/reference#tag/SellerTaxonomy)
and [BuyerTaxonomy](https://developers.etsy.com/documentation/reference#tag/BuyerTaxonomy)
for more information. | | shop\_location | string

Default: null

Filters by shop location. If location cannot be parsed, Etsy responds with an error. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of all active listings on Etsy paginated by their creation date. Without sort\_order listings will be returned newest-first by default. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/active Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/active ### Response samples * 200 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/findAllActiveListingsByShop) findAllActiveListingsByShop ------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of all active listings on Etsy in a specific shop, paginated by listing creation date. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | sort\_on | string

Default: "created"

Enum: "created" "price" "updated" "score"

The value to sort a search result of listings on. NOTES: a) `sort_on` only works when combined with one of the search options (keywords, region, etc.). b) when using `score` the returned results will always be in _descending_ order, regardless of the `sort_order` parameter. | | sort\_order | string

Default: "desc"

Enum: "asc" "ascending" "desc" "descending" "up" "down"

The ascending(up) or descending(down) order to sort listings by. NOTE: sort\_order only works when combined with one of the search options (keywords, region, etc.). | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | keywords | string

Default: null

Search term or phrase that must appear in all results. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** Retrieves a list of all active listings on Etsy in a specific shop, paginated by listing creation date. **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings/active Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/active ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/getListingsByListingIds) getListingsByListingIds ----------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Allows to query multiple listing ids at once. Limit 100 ids maximum per query. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### query Parameters | | | | --- | --- | | listing\_ids

required | Array of integers

The list of numeric IDS for the listings in a specific Etsy shop. | | includes | Array of strings

Default: null

Items Enum: "Shipping" "Images" "Shop" "User" "Translations" "Inventory" "Videos" "Personalization"

An enumerated string that attaches a valid association. Acceptable inputs are 'Shipping', 'Shop', 'Images', 'User', 'Translations', 'Videos', 'Inventory' and 'Personalization'. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of Listings **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/batch Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/batch ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string", * "shipping_profile": { * "shipping_profile_id": 1, * "title": "string", * "user_id": 1, * "origin_country_iso": "string", * "is_deleted": true, * "shipping_profile_destinations": [ * { * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "shipping_profile_upgrades": [ * { * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "origin_postal_code": "string", * "profile_type": "manual", * "domestic_handling_fee": 0, * "international_handling_fee": 0 }, * "user": { * "user_id": 1, * "primary_email": "user@example.com", * "first_name": "string", * "last_name": "string", * "image_url_75x75": "string" }, * "shop": { * "shop_id": 1, * "user_id": 1, * "shop_name": "string", * "create_date": 0, * "created_timestamp": 0, * "title": "string", * "announcement": "string", * "currency_code": "string", * "is_vacation": true, * "vacation_message": "string", * "sale_message": "string", * "digital_sale_message": "string", * "update_date": 0, * "updated_timestamp": 0, * "listing_active_count": 0, * "digital_listing_count": 0, * "login_name": "string", * "accepts_custom_requests": true, * "policy_welcome": "string", * "policy_payment": "string", * "policy_shipping": "string", * "policy_refunds": "string", * "policy_additional": "string", * "policy_seller_info": "string", * "policy_update_date": 0, * "policy_has_private_receipt_info": true, * "has_unstructured_policies": true, * "policy_privacy": "string", * "vacation_autoreply": "string", * "url": "string", * "image_url_760x100": "string", * "num_favorers": 0, * "languages": [ * "string" ], * "icon_url_fullxfull": "string", * "is_using_structured_policies": true, * "has_onboarded_structured_policies": true, * "include_dispute_form_link": true, * "is_direct_checkout_onboarded": true, * "is_etsy_payments_onboarded": true, * "is_calculated_eligible": true, * "is_opted_in_to_buyer_promise": true, * "is_shop_us_based": true, * "transaction_sold_count": 0, * "shipping_from_country_iso": "string", * "shop_location_country_iso": "string", * "review_count": 0, * "review_average": 0 }, * "images": [ * { * "listing_id": 1, * "listing_image_id": 1, * "hex_code": "string", * "red": 0, * "green": 0, * "blue": 0, * "hue": 0, * "saturation": 0, * "brightness": 0, * "is_black_and_white": true, * "creation_tsz": 0, * "created_timestamp": 0, * "rank": 0, * "url_75x75": "string", * "url_170x135": "string", * "url_570xN": "string", * "url_fullxfull": "string", * "full_height": 0, * "full_width": 0, * "alt_text": "string" } ], * "videos": [ * { * "video_id": 1, * "height": 0, * "width": 0, * "thumbnail_url": "string", * "video_url": "string", * "video_state": "active" } ], * "inventory": { * "products": [ * { * "product_id": 1, * "sku": "string", * "is_deleted": true, * "offerings": [ * { * "offering_id": 1, * "quantity": 0, * "is_enabled": true, * "is_deleted": true, * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "readiness_state_id": 1 } ], * "property_values": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ] } ], * "price_on_property": [ * 0 ], * "quantity_on_property": [ * 0 ], * "sku_on_property": [ * 0 ], * "readiness_state_on_property": [ * 1 ] }, * "production_partners": [ * { * "production_partner_id": 1, * "partner_name": "string", * "location": "string" } ], * "skus": [ * "string" ], * "translations": { * "de": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-GB": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-IN": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "en-US": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "es": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "fr": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "it": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "ja": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "nl": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "pl": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "pt": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "ru": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }, * "sv": { * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] } }, * "views": 0, * "personalization": { * "personalization_questions": [ * { * "question_id": 1, * "question_text": "string", * "instructions": "string", * "question_type": "string", * "required": true, * "max_allowed_characters": 0, * "max_allowed_files": 0, * "options": [ * { * "option_id": 1, * "label": "string" } ] } ] } } ] }` [](https://developers.etsy.com/documentation/reference#operation/getFeaturedListingsByShop) getFeaturedListingsByShop --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves Listings associated to a Shop that are featured. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of Listings **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings/featured Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/featured ### Response samples * 200 * 400 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/deleteListingProperty) deleteListingProperty ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes a property for a Listing. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | property\_id

required | integer \>= 1

The unique ID of an Etsy [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
. | ### Responses **204** The ListingProperty resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/listings/{listing\_id}/properties/{property\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/properties/{property\_id} ### Response samples * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/updateListingProperty) updateListingProperty ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates or populates the properties list defining product offerings for a listing. Each offering requires both a `value` and a `value_id` that are valid for a `scale_id` assigned to the listing or that you assign to the listing with this request. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | property\_id

required | integer \>= 1

The unique ID of an Etsy [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | value\_ids

required | Array of integers

An array of unique IDs of multiple Etsy [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
values. For example, if your listing offers different sizes of a product, then the value ID list contains value IDs for each size. | | values

required | Array of strings

An array of value strings for multiple Etsy [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
values. For example, if your listing offers different colored products, then the values array contains the color strings for each color. Note: parenthesis characters (`(` and `)`) are not allowed. | | scale\_id | integer \>= 1

The numeric ID of a single Etsy.com measurement scale. For example, for shoe size, there are three `scale_id`s available - `UK`, `US/Canada`, and `EU`, where `US/Canada` has `scale_id` 19. | ### Responses **200** A single listing property. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. put/v3/application/shops/{shop\_id}/listings/{listing\_id}/properties/{property\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/properties/{property\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] }` [](https://developers.etsy.com/documentation/reference#operation/getListingProperty) getListingProperty ------------------------------------------------------------------------------------------------------- Feedback only [Give feedback](https://github.com/etsy/open-api/discussions) Development for this endpoint is in progress. It will only return a 501 response. Retrieves a listing's property ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | property\_id

required | integer \>= 1

The unique ID of an Etsy [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
. | ### Responses **200** A single ListingProperty. **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. **501** This endpoint is not functional at this time. get/v3/application/listings/{listing\_id}/properties/{property\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/properties/{property\_id} ### Response samples * 200 * 400 * 404 * 500 * 501 Content type application/json Copy Expand all Collapse all `{ * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] }` [](https://developers.etsy.com/documentation/reference#operation/getListingProperties) getListingProperties ----------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Get a listing's properties ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ### Responses **200** A Listing's Properties **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings/{listing\_id}/properties Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/properties ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/updateListing) updateListing --------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates a listing, identified by a listing ID, for a specific shop identified by a shop ID. Note that this is a PATCH method type. When activating, or manually renewing a physical listing, the shipping profile referenced by the `shipping_profile_id`, and all of its fields, along with its entries and upgrades must be complete and valid. If the shipping profile is not complete and valid, we will throw an exception with an error message that guides the request sender to update whatever data is bad. Digital listings that are not made to order must have a file upload associated with it to be activated. While the listing is a draft, shipping profile and file upload are not required in any case. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | image\_ids | Array of integers

An array of numeric image IDs of the images in a listing, which can include up to 20 images. | | title | string

The listing's title string. When creating or updating a listing, valid title strings contain only letters, numbers, punctuation marks, mathematical symbols, whitespace characters, ™, ©, and ®. (regex: /\[^\\p{L}\\p{Nd}\\p{P}\\p{Sm}\\p{Zs}™©®\]/u) You can only use the %, :, & and + characters once each. | | description | string

A description string of the product for sale in the listing. | | materials | Array of strings Nullable

A list of material strings for materials used in the product. Valid materials strings contain only letters, numbers, and whitespace characters. (regex: /\[^\\p{L}\\p{Nd}\\p{Zs}\]/u) Default value is null. | | should\_auto\_renew | boolean

When true, renews a listing for four months upon expiration. | | shipping\_profile\_id | integer \>= 1 Nullable

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | | return\_policy\_id | integer \>= 1 Nullable

The numeric ID of the [Return Policy](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies)
. Required for active physical listings. This requirement does not apply to listings of EU-based shops. | | shop\_section\_id | integer Nullable

The numeric ID of the [shop section](https://developers.etsy.com/documentation/reference#tag/Shop-Section)
for this listing. Default value is null. | | item\_weight | number \[ 0 .. 1.79769313486e+308 \] Nullable

The numeric weight of the product measured in units set in 'item\_weight\_unit'. Default value is null. If set, the value must be greater than 0. | | item\_length | number \[ 0 .. 1.79769313486e+308 \] Nullable

The numeric length of the product measured in units set in 'item\_dimensions\_unit'. Default value is null. If set, the value must be greater than 0. | | item\_width | number \[ 0 .. 1.79769313486e+308 \] Nullable

The numeric width of the product measured in units set in 'item\_dimensions\_unit'. Default value is null. If set, the value must be greater than 0. | | item\_height | number \[ 0 .. 1.79769313486e+308 \] Nullable

The numeric height of the product measured in units set in 'item\_dimensions\_unit'. Default value is null. If set, the value must be greater than 0. | | item\_weight\_unit | string Nullable

Enum: "" "oz" "lb" "g" "kg"

A string defining the units used to measure the weight of the product. Default value is null. | | item\_dimensions\_unit | string Nullable

Enum: "" "in" "ft" "mm" "cm" "m" "yd" "inches"

A string defining the units used to measure the dimensions of the product. Default value is null. | | is\_taxable | boolean

When true, applicable [shop](https://developers.etsy.com/documentation/reference#tag/Shop)
tax rates apply to this listing at checkout. | | taxonomy\_id | integer \>= 1

The numerical taxonomy ID of the listing. See [SellerTaxonomy](https://developers.etsy.com/documentation/reference#tag/SellerTaxonomy)
and [BuyerTaxonomy](https://developers.etsy.com/documentation/reference#tag/BuyerTaxonomy)
for more information. | | tags | Array of strings Nullable

A comma-separated list of tag strings for the listing. When creating or updating a listing, valid tag strings contain only letters, numbers, whitespace characters, -, ', ™, ©, and ®. (regex: /\[^\\p{L}\\p{Nd}\\p{Zs}-'™©®\]/u) Default value is null. | | who\_made | string

Enum: "i\_did" "someone\_else" "collective"

An enumerated string indicating who made the product. Helps buyers locate the listing under the Handmade heading. Requires 'is\_supply' and 'when\_made'. | | when\_made | string

Enum: "made\_to\_order" "2020\_2026" "2010\_2019" "2007\_2009" "before\_2007" "2000\_2006" "1990s" "1980s" "1970s" "1960s" "1950s" "1940s" "1930s" "1920s" "1910s" "1900s" "1800s" "1700s" "before\_1700"

An enumerated string for the era in which the maker made the product in this listing. Helps buyers locate the listing under the Vintage heading. Requires 'is\_supply' and 'who\_made'. | | featured\_rank | integer Nullable

The positive non-zero numeric position in the featured listings of the shop, with rank 1 listings appearing in the left-most position in featured listing on a shop's home page. | | is\_personalizable | boolean

When true, this listing is personalizable. The default value is false. | | personalization\_is\_required | boolean

\[DEPRECATED\] When true, this listing requires personalization. The default value is false. NOTE: This field will be removed on Apr. 9th, 2026. See [https://developers.etsy.com/documentation/tutorials/personalization-migration](https://developers.etsy.com/documentation/tutorials/personalization-migration)
for migration details. | | personalization\_char\_count\_max | integer

\[DEPRECATED\] This is an integer value representing the maximum length for the personalization message entered by the buyer. Will only change if is\_personalizable is 'true'. Note: This field will be removed on Apr. 9th, 2026. See [https://developers.etsy.com/documentation/tutorials/personalization-migration](https://developers.etsy.com/documentation/tutorials/personalization-migration)
for migration details. | | personalization\_instructions | string

\[DEPRECATED\] A string representing instructions for the buyer to enter the personalization. Will only change if is\_personalizable is 'true'. Note: This field will be removed on Apr. 9th, 2026. See [https://developers.etsy.com/documentation/tutorials/personalization-migration](https://developers.etsy.com/documentation/tutorials/personalization-migration)
for migration details. | | state | string

Enum: "active" "inactive"

When _updating_ a listing, this value can be either `active` or `inactive`. Note: Setting a `draft` listing to `active` will also publish the listing on etsy.com and requires that the listing have an image set. Setting a `sold_out` listing to active will update the quantity to 1 and renew the listing on etsy.com. | | is\_supply | boolean

When true, tags the listing as a supply product, else indicates that it's a finished product. Helps buyers locate the listing under the Supplies heading. Requires 'who\_made' and 'when\_made'. | | production\_partner\_ids | Array of integers Nullable

An array of unique IDs of production partner ids. | | type | string Nullable

Enum: "physical" "download" "both"

An enumerated type string that indicates whether the listing is physical or a digital download. | ### Responses **200** A single ShopListing **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. patch/v3/application/shops/{shop\_id}/listings/{listing\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getListingsByShopReceipt) getListingsByShopReceipt ------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Gets all listings associated with a receipt. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | receipt\_id

required | integer \>= 1

The numeric ID for the [receipt](https://developers.etsy.com/documentation/reference#tag/Shop-Receipt)
associated to this transaction. | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A set of ShopListing resources. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/receipts/{receipt\_id}/listings Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/receipts/{receipt\_id}/listings ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/getListingsByShopReturnPolicy) getListingsByShopReturnPolicy ----------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Gets all listings associated with a Return Policy. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_r`) ##### path Parameters | | | | --- | --- | | return\_policy\_id

required | integer \>= 1

The numeric ID of the [Return Policy](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies)
. | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A set of ShopListing resources. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/policies/return/{return\_policy\_id}/listings Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/policies/return/{return\_policy\_id}/listings ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/getListingsByShopSectionId) getListingsByShopSectionId ----------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves all the listings from the section of a specific shop. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | shop\_section\_ids

required | Array of integers

A list of numeric IDS for all sections in a specific Etsy shop. | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | sort\_on | string

Default: "created"

Enum: "created" "price" "updated" "score"

The value to sort a search result of listings on. NOTES: a) `sort_on` only works when combined with one of the search options (keywords, region, etc.). b) when using `score` the returned results will always be in _descending_ order, regardless of the `sort_order` parameter. | | sort\_order | string

Default: "desc"

Enum: "asc" "ascending" "desc" "descending" "up" "down"

The ascending(up) or descending(down) order to sort listings by. NOTE: sort\_order only works when combined with one of the search options (keywords, region, etc.). | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of listings from a shop section. **400** There was a problem with the request data. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/shop-sections/listings Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shop-sections/listings ### Response samples * 200 * 400 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" } ] }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-File) ShopListing File ============================================================================================= [](https://developers.etsy.com/documentation/reference#operation/deleteListingFile) deleteListingFile ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes a file from a specific listing. When you delete the final file for a digital listing, the listing converts into a physical listing. The response to a delete request returns a list of the remaining file records associated with the given listing. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | listing\_file\_id

required | integer \>= 1

The unique numeric ID of a file associated with a digital listing. | ### Responses **204** The ShopListingFile resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/listings/{listing\_id}/files/{listing\_file\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/files/{listing\_file\_id} ### Response samples * 400 * 401 * 403 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getListingFile) getListingFile ----------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a single file associated with the given digital listing. Requesting a file from a physical listing returns an empty result. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | listing\_file\_id

required | integer \>= 1

The unique numeric ID of a file associated with a digital listing. | ### Responses **200** The metatdata for a file associated with a digital listing. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings/{listing\_id}/files/{listing\_file\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/files/{listing\_file\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_file_id": 1, * "listing_id": 1, * "rank": 0, * "filename": "string", * "filesize": "string", * "size_bytes": 0, * "filetype": "string", * "create_timestamp": 946684800, * "created_timestamp": 946684800 }` [](https://developers.etsy.com/documentation/reference#operation/getAllListingFiles) getAllListingFiles ------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves all the files associated with the given digital listing. Requesting files from a physical listing returns an empty result. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_r`) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ### Responses **200** A list of metadata objects for the file resources associated with a listing. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings/{listing\_id}/files Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/files ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_file_id": 1, * "listing_id": 1, * "rank": 0, * "filename": "string", * "filesize": "string", * "size_bytes": 0, * "filetype": "string", * "create_timestamp": 946684800, * "created_timestamp": 946684800 } ] }` [](https://developers.etsy.com/documentation/reference#operation/uploadListingFile) uploadListingFile ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Uploads a new file for a digital listing, or associates an existing file with a specific listing. You must either provide the `listing_file_id` of an existing file, or the name and binary file data for a file to upload. Associating an existing file to a physical listing converts the physical listing into a digital listing, which removes all shipping costs and any product and inventory variations. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### Request Body schema: multipart/form-data | | | | --- | --- | | listing\_file\_id | integer \>= 1

The unique numeric ID of a file associated with a digital listing. | | file | string Nullable

A binary file to upload. | | name | string

The file name string of a file to upload | | rank | integer \>= 1

Default: 1

The positive non-zero numeric position in the images displayed in a listing, with rank 1 images appearing in the left-most position in a listing. | ### Responses **201** The metadata for a file associated with a digital listing. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/listings/{listing\_id}/files Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/files ### Response samples * 201 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_file_id": 1, * "listing_id": 1, * "rank": 0, * "filename": "string", * "filesize": "string", * "size_bytes": 0, * "filetype": "string", * "create_timestamp": 946684800, * "created_timestamp": 946684800 }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-Image) ShopListing Image =============================================================================================== [](https://developers.etsy.com/documentation/reference#operation/deleteListingImage) deleteListingImage ------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 endpoint to delete a listing image. A copy of the file remains on our servers, and so a deleted image may be re-associated with the listing without re-uploading the original image; see uploadListingImage. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | listing\_image\_id

required | integer \>= 1

The numeric ID of the primary [listing image](https://developers.etsy.com/documentation/reference#tag/ShopListing-Image)
for this transaction. | ### Responses **204** The ListingImage resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/listings/{listing\_id}/images/{listing\_image\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/images/{listing\_image\_id} ### Response samples * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getListingImage) getListingImage ------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the references and metadata for a listing image with a specific image ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | listing\_image\_id

required | integer \>= 1

The numeric ID of the primary [listing image](https://developers.etsy.com/documentation/reference#tag/ShopListing-Image)
for this transaction. | ### Responses **200** A single ListingImage **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/images/{listing\_image\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/images/{listing\_image\_id} ### Response samples * 200 * 400 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_id": 1, * "listing_image_id": 1, * "hex_code": "string", * "red": 0, * "green": 0, * "blue": 0, * "hue": 0, * "saturation": 0, * "brightness": 0, * "is_black_and_white": true, * "creation_tsz": 0, * "created_timestamp": 0, * "rank": 0, * "url_75x75": "string", * "url_170x135": "string", * "url_570xN": "string", * "url_fullxfull": "string", * "full_height": 0, * "full_width": 0, * "alt_text": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getListingImages) getListingImages --------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves all listing image resources for a listing with a specific listing ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ### Responses **200** An array of ListingImage **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/images Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/images ### Response samples * 200 * 400 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "listing_id": 1, * "listing_image_id": 1, * "hex_code": "string", * "red": 0, * "green": 0, * "blue": 0, * "hue": 0, * "saturation": 0, * "brightness": 0, * "is_black_and_white": true, * "creation_tsz": 0, * "created_timestamp": 0, * "rank": 0, * "url_75x75": "string", * "url_170x135": "string", * "url_570xN": "string", * "url_fullxfull": "string", * "full_height": 0, * "full_width": 0, * "alt_text": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/uploadListingImage) uploadListingImage ------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Uploads or assigns an image to a listing identified by a shop ID with a listing ID. To upload a new image, set the image file as the value for the `image` parameter. You can assign a previously deleted image to a listing using the deleted image's image ID in the `listing_image_id` parameter. When a request contains both `image` and `listing_image_id` parameter values, the endpoint uploads the image in the `image` parameter only. Note: When uploading a new image, data such as colors and size may return as null values due to asynchronous processing of the image. Use getListingImage endpoint to fetch these values. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### Request Body schema: multipart/form-data | | | | --- | --- | | image | string Nullable

The file name string of a file to upload | | listing\_image\_id | integer \>= 1

The numeric ID of the primary [listing image](https://developers.etsy.com/documentation/reference#tag/ShopListing-Image)
for this transaction. | | rank | integer \>= 0

Default: 1

The positive non-zero numeric position in the images displayed in a listing, with rank 1 images appearing in the left-most position in a listing. | | overwrite | boolean

Default: false

When true, this request replaces the existing image at a given rank. | | is\_watermarked | boolean

Default: false

When true, indicates that the uploaded image has a watermark. | | alt\_text | string

Default: ""

Alt text for the listing image. Max length 500 characters. | ### Responses **201** A single ListingImage **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/listings/{listing\_id}/images Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/images ### Response samples * 201 * 400 * 401 * 403 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_id": 1, * "listing_image_id": 1, * "hex_code": "string", * "red": 0, * "green": 0, * "blue": 0, * "hue": 0, * "saturation": 0, * "brightness": 0, * "is_black_and_white": true, * "creation_tsz": 0, * "created_timestamp": 0, * "rank": 0, * "url_75x75": "string", * "url_170x135": "string", * "url_570xN": "string", * "url_fullxfull": "string", * "full_height": 0, * "full_width": 0, * "alt_text": "string" }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-Inventory) ShopListing Inventory ======================================================================================================= [](https://developers.etsy.com/documentation/reference#operation/getListingInventory) getListingInventory --------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the inventory record for a listing. Listings you did not edit using the Etsy.com inventory tools have no inventory records. This endpoint returns SKU data if you are the owner of the inventory records being fetched. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_r`) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | show\_deleted | boolean

A boolean value for inventory whether to include deleted products and their offerings. Default value is false. | | includes | string

Value: "Listing"

An enumerated string that attaches a valid association. Default value is null. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A single listing inventory record. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **422** There was a problem processing your request. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/inventory Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/inventory ### Response samples * 200 * 400 * 401 * 404 * 422 * 500 Content type application/json Copy Expand all Collapse all `{ * "products": [ * { * "product_id": 1, * "sku": "string", * "is_deleted": true, * "offerings": [ * { * "offering_id": 1, * "quantity": 0, * "is_enabled": true, * "is_deleted": true, * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "readiness_state_id": 1 } ], * "property_values": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ] } ], * "price_on_property": [ * 0 ], * "quantity_on_property": [ * 0 ], * "sku_on_property": [ * 0 ], * "readiness_state_on_property": [ * 1 ], * "listing": { * "listing_id": 1, * "user_id": 1, * "shop_id": 1, * "title": "string", * "description": "string", * "state": "active", * "creation_timestamp": 946684800, * "created_timestamp": 946684800, * "ending_timestamp": 946684800, * "original_creation_timestamp": 946684800, * "last_modified_timestamp": 946684800, * "updated_timestamp": 946684800, * "state_timestamp": 946684800, * "quantity": 0, * "shop_section_id": 1, * "featured_rank": 0, * "url": "string", * "num_favorers": 0, * "non_taxable": true, * "is_taxable": true, * "is_customizable": true, * "is_personalizable": true, * "personalization_is_required": true, * "personalization_char_count_max": 0, * "personalization_instructions": "string", * "listing_type": "physical", * "tags": [ * "string" ], * "materials": [ * "string" ], * "shipping_profile_id": 1, * "return_policy_id": 1, * "processing_min": 0, * "processing_max": 0, * "who_made": "i_did", * "when_made": "made_to_order", * "is_supply": true, * "item_weight": 0, * "item_weight_unit": "oz", * "item_length": 0, * "item_width": 0, * "item_height": 0, * "item_dimensions_unit": "in", * "is_private": true, * "style": [ * "string" ], * "file_data": "string", * "has_variations": true, * "should_auto_renew": true, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "taxonomy_id": 0, * "readiness_state_id": 1, * "suggested_title": "string" } }` [](https://developers.etsy.com/documentation/reference#operation/updateListingInventory) updateListingInventory --------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates the inventory for a listing identified by a listing ID. The update fails if the supplied values for product sku, offering quantity, and/or price are incompatible with values in `*_on_property_*` fields. When setting a price, assign a float equal to amount divided by divisor as specified in the Money resource. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ##### Request Body schema: application/json | | | | --- | --- | | products

required | Array of objects

A JSON array of products available in a listing, even if only one product. All field names in the JSON blobs are lowercase. | | price\_on\_property | Array of integers

An array of unique [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
ID integers for the properties that change product prices, if any. For example, if you charge specific prices for different sized products in the same listing, then this array contains the property ID for size. | | quantity\_on\_property | Array of integers

An array of unique [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
ID integers for the properties that change the quantity of the products, if any. For example, if you stock specific quantities of different colored products in the same listing, then this array contains the property ID for color. | | sku\_on\_property | Array of integers

An array of unique [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
ID integers for the properties that change the product SKU, if any. For example, if you use specific skus for different colored products in the same listing, then this array contains the property ID for color. | | readiness\_state\_on\_property | Array of integers Nullable

An array of unique [listing property](https://developers.etsy.com/documentation/reference#operation/getListingProperties)
ID integers for the properties that change processing profile, if any. For example, if you need specific processing profiles for different colored products in the same listing, then this array contains the property ID for color. | ### Responses **200** A single listing's inventory record. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. put/v3/application/listings/{listing\_id}/inventory Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/inventory ### Request samples * Payload Content type application/json Copy Expand all Collapse all `{ * "products": [ * { * "sku": "string", * "property_values": [ * { * "property_id": 1, * "value_ids": [ * 1 ], * "scale_id": 1, * "property_name": "string", * "values": [ * "string" ] } ], * "offerings": [ * { * "price": 0, * "quantity": 0, * "is_enabled": true, * "readiness_state_id": 1 } ] } ], * "price_on_property": [ * 0 ], * "quantity_on_property": [ * 0 ], * "sku_on_property": [ * 0 ], * "readiness_state_on_property": [ * 1 ] }` ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "products": [ * { * "product_id": 1, * "sku": "string", * "is_deleted": true, * "offerings": [ * { * "offering_id": 1, * "quantity": 0, * "is_enabled": true, * "is_deleted": true, * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "readiness_state_id": 1 } ], * "property_values": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ] } ], * "price_on_property": [ * 0 ], * "quantity_on_property": [ * 0 ], * "sku_on_property": [ * 0 ], * "readiness_state_on_property": [ * 1 ] }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-Offering) ShopListing Offering ===================================================================================================== [](https://developers.etsy.com/documentation/reference#operation/getListingOffering) getListingOffering ------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Get an Offering for a Listing ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1 | | product\_id

required | integer \>= 1 | | product\_offering\_id

required | integer \>= 1 | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A single ListingInventoryProductOffering **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/products/{product\_id}/offerings/{product\_offering\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/products/{product\_id}/offerings/{product\_offering\_id} ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "offering_id": 1, * "quantity": 0, * "is_enabled": true, * "is_deleted": true, * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "readiness_state_id": 1 }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-Personalization) ShopListing Personalization =================================================================================================================== [](https://developers.etsy.com/documentation/reference#operation/deleteListingPersonalization) deleteListingPersonalization --------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes personalization for a listing. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ### Responses **204** The ListingPersonalization resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/listings/{listing\_id}/personalization Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/personalization ### Response samples * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/updateListingPersonalization) updateListingPersonalization --------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates or updates personalization settings for a listing, allowing the seller to collect personalization from the buyer. This endpoint will fully replace any existing personalization on the listing. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | supports\_multiple\_personalization\_questions | boolean Nullable

This query parameter indicates that the caller supports up to 5 personalization questions and the following question types: 'text\_input', 'dropdown', 'unlabeled\_upload', 'labeled\_upload'. Sending this param without updating your application can lead to inadvertantly deleting seller-entered data. | ##### Request Body schema: application/json | | | | --- | --- | | personalization\_questions

required | Array of objects | ### Responses **201** A single Listing Personalization record **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/listings/{listing\_id}/personalization Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/personalization ### Request samples * Payload Content type application/json Copy Expand all Collapse all `{ * "personalization_questions": [ * { * "question_id": 1, * "question_text": "string", * "instructions": "string", * "question_type": "text_input", * "required": true, * "max_allowed_files": 0, * "max_allowed_characters": 0, * "options": [ * { * "option_id": 1, * "label": "string" } ] } ] }` ### Response samples * 201 * 400 * 401 * 403 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "personalization_questions": [ * { * "question_id": 1, * "question_text": "string", * "instructions": "string", * "question_type": "string", * "required": true, * "max_allowed_characters": 0, * "max_allowed_files": 0, * "options": [ * { * "option_id": 1, * "label": "string" } ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/getListingPersonalization) getListingPersonalization --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a listing's personalization questions by listing ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ### Responses **200** A listing personalization questions **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/personalization Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/personalization ### Response samples * 200 * 400 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "personalization_questions": [ * { * "question_id": 1, * "question_text": "string", * "instructions": "string", * "question_type": "string", * "required": true, * "max_allowed_characters": 0, * "max_allowed_files": 0, * "options": [ * { * "option_id": 1, * "label": "string" } ] } ] }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-Product) ShopListing Product =================================================================================================== [](https://developers.etsy.com/documentation/reference#operation/getListingProduct) getListingProduct ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 endpoint to retrieve a ListingProduct by ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_r`) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The listing to return a ListingProduct for. | | product\_id

required | integer \>= 1

The numeric ID for a specific [product](https://developers.etsy.com/documentation/reference#tag/ShopListing-Product)
purchased from a listing. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A single ListingInventoryProduct **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/inventory/products/{product\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/inventory/products/{product\_id} ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "product_id": 1, * "sku": "string", * "is_deleted": true, * "offerings": [ * { * "offering_id": 1, * "quantity": 0, * "is_enabled": true, * "is_deleted": true, * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "readiness_state_id": 1 } ], * "property_values": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ] }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-Translation) ShopListing Translation =========================================================================================================== [](https://developers.etsy.com/documentation/reference#operation/createListingTranslation) createListingTranslation ------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates a ListingTranslation by listing\_id and language ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | language

required | string

The IETF language tag for the language of this translation. Ex: `de`, `en`, `es`, `fr`, `it`, `ja`, `nl`, `pl`, `pt`. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | title

required | string

The title of the Listing of this Translation. | | description

required | string

The description of the Listing of this Translation. | | tags | Array of strings

The tags of the Listing of this Translation. | ### Responses **200** A single ListingTranslation **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/listings/{listing\_id}/translations/{language} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/translations/{language} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }` [](https://developers.etsy.com/documentation/reference#operation/getListingTranslation) getListingTranslation ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Get a Translation for a Listing in the given language ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | language

required | string

The IETF language tag for the language of this translation. Ex: `de`, `en`, `es`, `fr`, `it`, `ja`, `nl`, `pl`, `pt`. | ### Responses **200** A single ListingTranslation **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings/{listing\_id}/translations/{language} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/translations/{language} ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }` [](https://developers.etsy.com/documentation/reference#operation/updateListingTranslation) updateListingTranslation ------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates a ListingTranslation by listing\_id and language ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | language

required | string

The IETF language tag for the language of this translation. Ex: `de`, `en`, `es`, `fr`, `it`, `ja`, `nl`, `pl`, `pt`. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | title

required | string

The title of the Listing of this Translation. | | description

required | string

The description of the Listing of this Translation. | | tags | Array of strings

The tags of the Listing of this Translation. | ### Responses **200** A single ListingTranslation **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. put/v3/application/shops/{shop\_id}/listings/{listing\_id}/translations/{language} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/translations/{language} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "listing_id": 1, * "language": "string", * "title": "string", * "description": "string", * "tags": [ * "string" ] }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-VariationImage) ShopListing VariationImage ================================================================================================================= [](https://developers.etsy.com/documentation/reference#operation/getListingVariationImages) getListingVariationImages --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Gets all variation images on a listing. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ### Responses **200** A list of ListingVariationImages **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings/{listing\_id}/variation-images Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/variation-images ### Response samples * 200 * 400 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "property_id": 1, * "value_id": 1, * "value": "string", * "image_id": 1 } ] }` [](https://developers.etsy.com/documentation/reference#operation/updateVariationImages) updateVariationImages ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates variation images on a listing. `variation_images` is an array with inputs for the `property_id`, `value_id`, and `image_id` fields. `image_ids` are associated with a `ListingImage` on the listing associated with the provided `listing_id`. `property_id` and `value_id` pairs are associated with a `ListingProduct` on the listing associated with the provided `listing_id`. `variation_images` should not contain any duplicates. `variation_images` does not contain more than one `property_id` as variation images can only be associated on one property. The update overwrites all existing variation images on a listing, so if your request is successful, the variation images on the listing will be exactly those you specify. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### Request Body schema: application/json | | | | --- | --- | | variation\_images

required | Array of objects

A list of variation image data. | ### Responses **200** A single ListingVariationImage **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/listings/{listing\_id}/variation-images Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/variation-images ### Request samples * Payload Content type application/json Copy Expand all Collapse all `{ * "variation_images": [ * { * "property_id": 1, * "value_id": 1, * "image_id": 1 } ] }` ### Response samples * 200 * 400 * 401 * 403 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "property_id": 1, * "value_id": 1, * "value": "string", * "image_id": 1 } ] }` [](https://developers.etsy.com/documentation/reference#tag/ShopListing-Video) ShopListing Video =============================================================================================== [](https://developers.etsy.com/documentation/reference#operation/deleteListingVideo) deleteListingVideo ------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 endpoint to delete a listing video. A copy of the video remains on our servers, and so a deleted video may be re-associated with the listing without re-uploading the original video; see uploadListingVideo. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | | video\_id

required | integer \>= 1

The unique ID of a video associated with a listing. | ### Responses **204** The ListingVideo resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/listings/{listing\_id}/videos/{video\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/videos/{video\_id} ### Response samples * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getListingVideo) getListingVideo ------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a single video associated with the given listing. Requesting a video from a listing returns an empty result. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | video\_id

required | integer \>= 1

The unique ID of a video associated with a listing. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ### Responses **200** The metatdata for a video associated with a listing. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/videos/{video\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/videos/{video\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "video_id": 1, * "height": 0, * "width": 0, * "thumbnail_url": "string", * "video_url": "string", * "video_state": "active" }` [](https://developers.etsy.com/documentation/reference#operation/getListingVideos) getListingVideos --------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves all listing video resources for a listing with a specific listing ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ### Responses **200** A list of videos for a listing **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/videos Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/videos ### Response samples * 200 * 400 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "video_id": 1, * "height": 0, * "width": 0, * "thumbnail_url": "string", * "video_url": "string", * "video_state": "active" } ] }` [](https://developers.etsy.com/documentation/reference#operation/uploadListingVideo) uploadListingVideo ------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Uploads a new video for a listing, or associates an existing video with a specific listing. You must either provide the `video_id` of an existing video, or the name and binary file data for a video to upload. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`listings_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### Request Body schema: multipart/form-data | | | | --- | --- | | video\_id | integer \>= 1

The unique ID of a video associated with a listing. | | video | string Nullable

A video file to upload. | | name | string

The file name string for the video to upload. | ### Responses **201** The metadata for a file associated with a digital listing. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/listings/{listing\_id}/videos Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/videos ### Response samples * 201 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "video_id": 1, * "height": 0, * "width": 0, * "thumbnail_url": "string", * "video_url": "string", * "video_state": "active" }` [](https://developers.etsy.com/documentation/reference#tag/Other) Other ======================================================================= [](https://developers.etsy.com/documentation/reference#operation/ping) ping --------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Check to confirm connectivity to the Etsy API with an application ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ### Responses **200** A confirmation that the current application has access to the Open API **401** Missing or invalid API key. **404** App does not have the proper permissions to access this resource. **500** The server encountered an internal error. See the error message for details. get/v3/application/openapi-ping Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/openapi-ping ### Response samples * 200 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "application_id": 1 }` [](https://developers.etsy.com/documentation/reference#operation/tokenScopes) tokenScopes ----------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Check the scopes of the provided token ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | token

required | string | ### Responses **200** A confirmation that the current application has access to the Open API **401** Missing or invalid API key. **500** The server encountered an internal error. See the error message for details. post/v3/application/scopes Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/scopes ### Response samples * 200 * 401 * 500 Content type application/json Copy Expand all Collapse all `{ }` [](https://developers.etsy.com/documentation/reference#tag/Ledger-Entry) Ledger Entry ===================================================================================== [](https://developers.etsy.com/documentation/reference#operation/getShopPaymentAccountLedgerEntry) getShopPaymentAccountLedgerEntry ----------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Get a single Shop Payment Account Ledger's Entry ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | ledger\_entry\_id

required | integer \>= 1

The unique ID of the shop owner ledger entry. | ### Responses **200** A single of PaymentAccountLedgerEntry **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/payment-account/ledger-entries/{ledger\_entry\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/payment-account/ledger-entries/{ledger\_entry\_id} ### Response samples * 200 * 400 * 401 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "entry_id": 1, * "ledger_id": 1, * "sequence_number": 0, * "amount": 0, * "currency": "string", * "description": "string", * "balance": 0, * "create_date": 0, * "created_timestamp": 0, * "ledger_type": "string", * "reference_type": "string", * "reference_id": "string", * "parent_entry_id": 0, * "payment_adjustments": [ * { * "payment_adjustment_id": 1, * "payment_id": 1, * "status": "string", * "is_success": true, * "user_id": 1, * "reason_code": "string", * "total_adjustment_amount": 0, * "shop_total_adjustment_amount": 0, * "buyer_total_adjustment_amount": 0, * "total_fee_adjustment_amount": 0, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "payment_adjustment_items": [ * { * "payment_adjustment_id": 1, * "payment_adjustment_item_id": 1, * "adjustment_type": "string", * "amount": 0, * "shop_amount": 0, * "transaction_id": 1, * "bill_payment_id": 1, * "created_timestamp": 946684800, * "updated_timestamp": 946684800 } ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/getShopPaymentAccountLedgerEntries) getShopPaymentAccountLedgerEntries --------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Get a Shop Payment Account Ledger's Entries ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | min\_created

required | integer \>= 946684800

The earliest unix timestamp for when a record was created. | | max\_created

required | integer \>= 946684800

The latest unix timestamp for when a record was created. | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | ### Responses **200** A list of PaymentAccountLedgerEntries **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/payment-account/ledger-entries Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/payment-account/ledger-entries ### Response samples * 200 * 400 * 401 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "entry_id": 1, * "ledger_id": 1, * "sequence_number": 0, * "amount": 0, * "currency": "string", * "description": "string", * "balance": 0, * "create_date": 0, * "created_timestamp": 0, * "ledger_type": "string", * "reference_type": "string", * "reference_id": "string", * "parent_entry_id": 0, * "payment_adjustments": [ * { * "payment_adjustment_id": 1, * "payment_id": 1, * "status": "string", * "is_success": true, * "user_id": 1, * "reason_code": "string", * "total_adjustment_amount": 0, * "shop_total_adjustment_amount": 0, * "buyer_total_adjustment_amount": 0, * "total_fee_adjustment_amount": 0, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "payment_adjustment_items": [ * { * "payment_adjustment_id": 1, * "payment_adjustment_item_id": 1, * "adjustment_type": "string", * "amount": 0, * "shop_amount": 0, * "transaction_id": 1, * "bill_payment_id": 1, * "created_timestamp": 946684800, * "updated_timestamp": 946684800 } ] } ] } ] }` [](https://developers.etsy.com/documentation/reference#tag/Payment) Payment =========================================================================== [](https://developers.etsy.com/documentation/reference#operation/getPaymentAccountLedgerEntryPayments) getPaymentAccountLedgerEntryPayments ------------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Get a Payment from a PaymentAccount Ledger Entry ID, if applicable ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | ledger\_entry\_ids

required | Array of integers | ### Responses **200** A list of Payments **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/payment-account/ledger-entries/payments Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/payment-account/ledger-entries/payments ### Response samples * 200 * 400 * 401 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "payment_id": 1, * "buyer_user_id": 1, * "shop_id": 1, * "receipt_id": 1, * "amount_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "amount_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "amount_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "currency": "string", * "shop_currency": "string", * "buyer_currency": "string", * "shipping_user_id": 1, * "shipping_address_id": 1, * "billing_address_id": 9223372036854776000, * "status": "string", * "shipped_timestamp": 946684800, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "payment_adjustments": [ * { * "payment_adjustment_id": 1, * "payment_id": 1, * "status": "string", * "is_success": true, * "user_id": 1, * "reason_code": "string", * "total_adjustment_amount": 0, * "shop_total_adjustment_amount": 0, * "buyer_total_adjustment_amount": 0, * "total_fee_adjustment_amount": 0, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "payment_adjustment_items": [ * { * "payment_adjustment_id": 1, * "payment_adjustment_item_id": 1, * "adjustment_type": "string", * "amount": 0, * "shop_amount": 0, * "transaction_id": 1, * "bill_payment_id": 1, * "created_timestamp": 946684800, * "updated_timestamp": 946684800 } ] } ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/getShopPaymentByReceiptId) getShopPaymentByReceiptId --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a payment from a specific receipt, identified by `receipt_id`, from a specific shop, identified by `shop_id` ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | receipt\_id

required | integer \>= 1

The numeric ID for the [receipt](https://developers.etsy.com/documentation/reference#tag/Shop-Receipt)
associated to this transaction. | ### Responses **200** A single payment **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/receipts/{receipt\_id}/payments Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/receipts/{receipt\_id}/payments ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "payment_id": 1, * "buyer_user_id": 1, * "shop_id": 1, * "receipt_id": 1, * "amount_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "amount_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "amount_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "currency": "string", * "shop_currency": "string", * "buyer_currency": "string", * "shipping_user_id": 1, * "shipping_address_id": 1, * "billing_address_id": 9223372036854776000, * "status": "string", * "shipped_timestamp": 946684800, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "payment_adjustments": [ * { * "payment_adjustment_id": 1, * "payment_id": 1, * "status": "string", * "is_success": true, * "user_id": 1, * "reason_code": "string", * "total_adjustment_amount": 0, * "shop_total_adjustment_amount": 0, * "buyer_total_adjustment_amount": 0, * "total_fee_adjustment_amount": 0, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "payment_adjustment_items": [ * { * "payment_adjustment_id": 1, * "payment_adjustment_item_id": 1, * "adjustment_type": "string", * "amount": 0, * "shop_amount": 0, * "transaction_id": 1, * "bill_payment_id": 1, * "created_timestamp": 946684800, * "updated_timestamp": 946684800 } ] } ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/getPayments) getPayments ----------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of payments from a shop identified by `shop_id`. You can also filter results using a list of payment IDs. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | payment\_ids

required | Array of integers

A comma-separated array of Payment IDs numbers. | ### Responses **200** A list of payments from a specific shop. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/payments Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/payments ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "payment_id": 1, * "buyer_user_id": 1, * "shop_id": 1, * "receipt_id": 1, * "amount_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "amount_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "amount_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "posted_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_gross": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_fees": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "adjusted_net": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "currency": "string", * "shop_currency": "string", * "buyer_currency": "string", * "shipping_user_id": 1, * "shipping_address_id": 1, * "billing_address_id": 9223372036854776000, * "status": "string", * "shipped_timestamp": 946684800, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "payment_adjustments": [ * { * "payment_adjustment_id": 1, * "payment_id": 1, * "status": "string", * "is_success": true, * "user_id": 1, * "reason_code": "string", * "total_adjustment_amount": 0, * "shop_total_adjustment_amount": 0, * "buyer_total_adjustment_amount": 0, * "total_fee_adjustment_amount": 0, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "payment_adjustment_items": [ * { * "payment_adjustment_id": 1, * "payment_adjustment_item_id": 1, * "adjustment_type": "string", * "amount": 0, * "shop_amount": 0, * "transaction_id": 1, * "bill_payment_id": 1, * "created_timestamp": 946684800, * "updated_timestamp": 946684800 } ] } ] } ] }` [](https://developers.etsy.com/documentation/reference#tag/Shop-Receipt) Shop Receipt ===================================================================================== [](https://developers.etsy.com/documentation/reference#operation/getShopReceipt) getShopReceipt ----------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a receipt, identified by a receipt id, from an Etsy shop. **NOTE** Access to ShopReceipt's first\_line, second\_line, city, state, zip, country\_iso and formatted\_address is contingent in some regions to a preferred partnership status with Etsy ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | receipt\_id

required | integer \>= 1

The numeric ID for the [receipt](https://developers.etsy.com/documentation/reference#tag/Shop-Receipt)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A single Shop Receipt **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/receipts/{receipt\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/receipts/{receipt\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "receipt_id": 1, * "receipt_type": 0, * "seller_user_id": 1, * "seller_email": "user@example.com", * "buyer_user_id": 1, * "buyer_email": "string", * "name": "string", * "first_line": "string", * "second_line": "string", * "city": "string", * "state": "string", * "zip": "string", * "status": "paid", * "formatted_address": "string", * "country_iso": "string", * "payment_method": "string", * "payment_email": "string", * "message_from_seller": "string", * "message_from_buyer": "string", * "message_from_payment": "string", * "is_paid": true, * "is_shipped": true, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "is_gift": true, * "gift_message": "string", * "gift_sender": "string", * "grandtotal": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "subtotal": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_tax_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_vat_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "discount_amt": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "gift_wrap_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipments": [ * { * "receipt_shipping_id": 1, * "shipment_notification_timestamp": 946684800, * "carrier_name": "string", * "tracking_code": "string" } ], * "transactions": [ * { * "transaction_id": 1, * "title": "string", * "description": "string", * "seller_user_id": 1, * "buyer_user_id": 1, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "paid_timestamp": 946684800, * "shipped_timestamp": 946684800, * "quantity": 0, * "listing_image_id": 1, * "receipt_id": 1, * "is_digital": true, * "file_data": "string", * "listing_id": 0, * "transaction_type": "string", * "product_id": 1, * "sku": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "variations": [ * { * "property_id": 0, * "value_id": 0, * "formatted_name": "string", * "formatted_value": "string" } ], * "product_data": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ], * "shipping_profile_id": 1, * "min_processing_days": 0, * "max_processing_days": 0, * "shipping_method": "string", * "shipping_upgrade": "string", * "expected_ship_date": 946684800, * "buyer_coupon": 0, * "shop_coupon": 0 } ], * "refunds": [ * { * "amount": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "created_timestamp": 946684800, * "reason": "string", * "note_from_issuer": "string", * "status": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/updateShopReceipt) updateShopReceipt ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates the status of a receipt, identified by a receipt id, from an Etsy shop. **NOTE** Access to ShopReceipt's first\_line, second\_line, city, state, zip, country\_iso and formatted\_address is contingent in some regions to a preferred partnership status with Etsy ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | receipt\_id

required | integer \>= 1

The numeric ID for the [receipt](https://developers.etsy.com/documentation/reference#tag/Shop-Receipt)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | was\_shipped | boolean Nullable

When `true`, returns receipts where the seller shipped the product(s) in this receipt. When `false`, returns receipts where shipment has not been set. | | was\_paid | boolean Nullable

When `true`, returns receipts where the seller has recieved payment for the receipt. When `false`, returns receipts where payment has not been received. | ### Responses **200** Update A Shop Receipt **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. put/v3/application/shops/{shop\_id}/receipts/{receipt\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/receipts/{receipt\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "receipt_id": 1, * "receipt_type": 0, * "seller_user_id": 1, * "seller_email": "user@example.com", * "buyer_user_id": 1, * "buyer_email": "string", * "name": "string", * "first_line": "string", * "second_line": "string", * "city": "string", * "state": "string", * "zip": "string", * "status": "paid", * "formatted_address": "string", * "country_iso": "string", * "payment_method": "string", * "payment_email": "string", * "message_from_seller": "string", * "message_from_buyer": "string", * "message_from_payment": "string", * "is_paid": true, * "is_shipped": true, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "is_gift": true, * "gift_message": "string", * "gift_sender": "string", * "grandtotal": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "subtotal": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_tax_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_vat_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "discount_amt": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "gift_wrap_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipments": [ * { * "receipt_shipping_id": 1, * "shipment_notification_timestamp": 946684800, * "carrier_name": "string", * "tracking_code": "string" } ], * "transactions": [ * { * "transaction_id": 1, * "title": "string", * "description": "string", * "seller_user_id": 1, * "buyer_user_id": 1, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "paid_timestamp": 946684800, * "shipped_timestamp": 946684800, * "quantity": 0, * "listing_image_id": 1, * "receipt_id": 1, * "is_digital": true, * "file_data": "string", * "listing_id": 0, * "transaction_type": "string", * "product_id": 1, * "sku": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "variations": [ * { * "property_id": 0, * "value_id": 0, * "formatted_name": "string", * "formatted_value": "string" } ], * "product_data": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ], * "shipping_profile_id": 1, * "min_processing_days": 0, * "max_processing_days": 0, * "shipping_method": "string", * "shipping_upgrade": "string", * "expected_ship_date": 946684800, * "buyer_coupon": 0, * "shop_coupon": 0 } ], * "refunds": [ * { * "amount": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "created_timestamp": 946684800, * "reason": "string", * "note_from_issuer": "string", * "status": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/getShopReceipts) getShopReceipts ------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Requests the Shop Receipts from a specific Shop, unfiltered or filtered by receipt id range or offset, date, paid, and/or shipped purchases. **NOTE** Access to ShopReceipt's first\_line, second\_line, city, state, zip, country\_iso and formatted\_address is contingent in some regions to a preferred partnership status with Etsy ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | min\_created | integer \>= 946684800

Default: null

The earliest unix timestamp for when a record was created. | | max\_created | integer \>= 946684800

Default: null

The latest unix timestamp for when a record was created. | | min\_last\_modified | integer \>= 946684800

Default: null

The earliest unix timestamp for when a record last changed. | | max\_last\_modified | integer \>= 946684800

Default: null

The latest unix timestamp for when a record last changed. | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | sort\_on | string

Default: "created"

Enum: "created" "updated" "receipt\_id"

The value to sort a search result of listings on. | | sort\_order | string

Default: "desc"

Enum: "asc" "ascending" "desc" "descending" "up" "down"

The ascending(up) or descending(down) order to sort receipts by. | | was\_paid | boolean Nullable

When `true`, returns receipts where the seller has recieved payment for the receipt. When `false`, returns receipts where payment has not been received. | | was\_shipped | boolean Nullable

When `true`, returns receipts where the seller shipped the product(s) in this receipt. When `false`, returns receipts where shipment has not been set. | | was\_delivered | boolean Nullable

When `true`, returns receipts that have been marked as delivered. When `false`, returns receipts where shipment has not been marked as delivered. | | was\_canceled | boolean Nullable

When `true`, the endpoint will only return the canceled receipts. When `false`, the endpoint will only return non-canceled receipts. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of Shop Receipts **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/receipts Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/receipts ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "receipt_id": 1, * "receipt_type": 0, * "seller_user_id": 1, * "seller_email": "user@example.com", * "buyer_user_id": 1, * "buyer_email": "string", * "name": "string", * "first_line": "string", * "second_line": "string", * "city": "string", * "state": "string", * "zip": "string", * "status": "paid", * "formatted_address": "string", * "country_iso": "string", * "payment_method": "string", * "payment_email": "string", * "message_from_seller": "string", * "message_from_buyer": "string", * "message_from_payment": "string", * "is_paid": true, * "is_shipped": true, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "is_gift": true, * "gift_message": "string", * "gift_sender": "string", * "grandtotal": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "subtotal": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_tax_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_vat_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "discount_amt": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "gift_wrap_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipments": [ * { * "receipt_shipping_id": 1, * "shipment_notification_timestamp": 946684800, * "carrier_name": "string", * "tracking_code": "string" } ], * "transactions": [ * { * "transaction_id": 1, * "title": "string", * "description": "string", * "seller_user_id": 1, * "buyer_user_id": 1, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "paid_timestamp": 946684800, * "shipped_timestamp": 946684800, * "quantity": 0, * "listing_image_id": 1, * "receipt_id": 1, * "is_digital": true, * "file_data": "string", * "listing_id": 0, * "transaction_type": "string", * "product_id": 1, * "sku": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "variations": [ * { * "property_id": 0, * "value_id": 0, * "formatted_name": "string", * "formatted_value": "string" } ], * "product_data": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ], * "shipping_profile_id": 1, * "min_processing_days": 0, * "max_processing_days": 0, * "shipping_method": "string", * "shipping_upgrade": "string", * "expected_ship_date": 946684800, * "buyer_coupon": 0, * "shop_coupon": 0 } ], * "refunds": [ * { * "amount": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "created_timestamp": 946684800, * "reason": "string", * "note_from_issuer": "string", * "status": "string" } ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/createReceiptShipment) createReceiptShipment ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Submits tracking information for a Shop Receipt, which creates a Shop Receipt Shipment entry for the given receipt\_id. Each time you successfully submit tracking info, Etsy sends a notification email to the buyer User. When send\_bcc is true, Etsy sends shipping notifications to the seller as well. When tracking\_code and carrier\_name aren't sent, the receipt is marked as shipped only. If the carrier is not supported, you may use `other` as the carrier name so you can provide the tracking code. **NOTES** When shipping within the United States AND the order is over $10 _or_ when shipping to India, tracking code and carrier name ARE required. Access to ShopReceipt's first\_line, second\_line, city, state, zip, country\_iso and formatted\_address is contingent in some regions to a preferred partnership status with Etsy ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | receipt\_id

required | integer \>= 1

The receipt to submit tracking for. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | tracking\_code | string

The tracking code for this receipt. | | carrier\_name | string

The carrier name for this receipt. | | send\_bcc | boolean

If true, the shipping notification will be sent to the seller as well | | note\_to\_buyer | string

Message to include in notification to the buyer. | ### Responses **200** A single ShopReceipt **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/receipts/{receipt\_id}/tracking Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/receipts/{receipt\_id}/tracking ### Response samples * 200 * 400 * 401 * 403 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "receipt_id": 1, * "receipt_type": 0, * "seller_user_id": 1, * "seller_email": "user@example.com", * "buyer_user_id": 1, * "buyer_email": "string", * "name": "string", * "first_line": "string", * "second_line": "string", * "city": "string", * "state": "string", * "zip": "string", * "status": "paid", * "formatted_address": "string", * "country_iso": "string", * "payment_method": "string", * "payment_email": "string", * "message_from_seller": "string", * "message_from_buyer": "string", * "message_from_payment": "string", * "is_paid": true, * "is_shipped": true, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800, * "is_gift": true, * "gift_message": "string", * "gift_sender": "string", * "grandtotal": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "subtotal": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_tax_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "total_vat_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "discount_amt": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "gift_wrap_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipments": [ * { * "receipt_shipping_id": 1, * "shipment_notification_timestamp": 946684800, * "carrier_name": "string", * "tracking_code": "string" } ], * "transactions": [ * { * "transaction_id": 1, * "title": "string", * "description": "string", * "seller_user_id": 1, * "buyer_user_id": 1, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "paid_timestamp": 946684800, * "shipped_timestamp": 946684800, * "quantity": 0, * "listing_image_id": 1, * "receipt_id": 1, * "is_digital": true, * "file_data": "string", * "listing_id": 0, * "transaction_type": "string", * "product_id": 1, * "sku": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "variations": [ * { * "property_id": 0, * "value_id": 0, * "formatted_name": "string", * "formatted_value": "string" } ], * "product_data": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ], * "shipping_profile_id": 1, * "min_processing_days": 0, * "max_processing_days": 0, * "shipping_method": "string", * "shipping_upgrade": "string", * "expected_ship_date": 946684800, * "buyer_coupon": 0, * "shop_coupon": 0 } ], * "refunds": [ * { * "amount": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "created_timestamp": 946684800, * "reason": "string", * "note_from_issuer": "string", * "status": "string" } ] }` [](https://developers.etsy.com/documentation/reference#tag/Shop-Receipt-Transactions) Shop Receipt Transactions =============================================================================================================== [](https://developers.etsy.com/documentation/reference#operation/getShopReceiptTransactionsByListing) getShopReceiptTransactionsByListing ----------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the list of transactions associated with a listing. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of transactions **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/listings/{listing\_id}/transactions Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/listings/{listing\_id}/transactions ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "transaction_id": 1, * "title": "string", * "description": "string", * "seller_user_id": 1, * "buyer_user_id": 1, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "paid_timestamp": 946684800, * "shipped_timestamp": 946684800, * "quantity": 0, * "listing_image_id": 1, * "receipt_id": 1, * "is_digital": true, * "file_data": "string", * "listing_id": 0, * "transaction_type": "string", * "product_id": 1, * "sku": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "variations": [ * { * "property_id": 0, * "value_id": 0, * "formatted_name": "string", * "formatted_value": "string" } ], * "product_data": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ], * "shipping_profile_id": 1, * "min_processing_days": 0, * "max_processing_days": 0, * "shipping_method": "string", * "shipping_upgrade": "string", * "expected_ship_date": 946684800, * "buyer_coupon": 0, * "shop_coupon": 0 } ] }` [](https://developers.etsy.com/documentation/reference#operation/getShopReceiptTransactionsByReceipt) getShopReceiptTransactionsByReceipt ----------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the list of transactions associated with a specific receipt. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | receipt\_id

required | integer \>= 1

The numeric ID for the [receipt](https://developers.etsy.com/documentation/reference#tag/Shop-Receipt)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of transactions **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/receipts/{receipt\_id}/transactions Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/receipts/{receipt\_id}/transactions ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "transaction_id": 1, * "title": "string", * "description": "string", * "seller_user_id": 1, * "buyer_user_id": 1, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "paid_timestamp": 946684800, * "shipped_timestamp": 946684800, * "quantity": 0, * "listing_image_id": 1, * "receipt_id": 1, * "is_digital": true, * "file_data": "string", * "listing_id": 0, * "transaction_type": "string", * "product_id": 1, * "sku": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "variations": [ * { * "property_id": 0, * "value_id": 0, * "formatted_name": "string", * "formatted_value": "string" } ], * "product_data": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ], * "shipping_profile_id": 1, * "min_processing_days": 0, * "max_processing_days": 0, * "shipping_method": "string", * "shipping_upgrade": "string", * "expected_ship_date": 946684800, * "buyer_coupon": 0, * "shop_coupon": 0 } ] }` [](https://developers.etsy.com/documentation/reference#operation/getShopReceiptTransaction) getShopReceiptTransaction --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a transaction by transaction ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | transaction\_id

required | integer \>= 1

The unique numeric ID for a transaction. | ### Responses **200** A single transaction **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/transactions/{transaction\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/transactions/{transaction\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "transaction_id": 1, * "title": "string", * "description": "string", * "seller_user_id": 1, * "buyer_user_id": 1, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "paid_timestamp": 946684800, * "shipped_timestamp": 946684800, * "quantity": 0, * "listing_image_id": 1, * "receipt_id": 1, * "is_digital": true, * "file_data": "string", * "listing_id": 0, * "transaction_type": "string", * "product_id": 1, * "sku": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "variations": [ * { * "property_id": 0, * "value_id": 0, * "formatted_name": "string", * "formatted_value": "string" } ], * "product_data": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ], * "shipping_profile_id": 1, * "min_processing_days": 0, * "max_processing_days": 0, * "shipping_method": "string", * "shipping_upgrade": "string", * "expected_ship_date": 946684800, * "buyer_coupon": 0, * "shop_coupon": 0 }` [](https://developers.etsy.com/documentation/reference#operation/getShopReceiptTransactionsByShop) getShopReceiptTransactionsByShop ----------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the list of transactions associated with a shop. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`transactions_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | legacy | boolean

This parameter needed to enable new parameters and response values related to processing profiles. | ### Responses **200** A list of transactions **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/transactions Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/transactions ### Response samples * 200 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "transaction_id": 1, * "title": "string", * "description": "string", * "seller_user_id": 1, * "buyer_user_id": 1, * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "paid_timestamp": 946684800, * "shipped_timestamp": 946684800, * "quantity": 0, * "listing_image_id": 1, * "receipt_id": 1, * "is_digital": true, * "file_data": "string", * "listing_id": 0, * "transaction_type": "string", * "product_id": 1, * "sku": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "variations": [ * { * "property_id": 0, * "value_id": 0, * "formatted_name": "string", * "formatted_value": "string" } ], * "product_data": [ * { * "property_id": 1, * "property_name": "string", * "scale_id": 1, * "scale_name": "string", * "value_ids": [ * 1 ], * "values": [ * "string" ] } ], * "shipping_profile_id": 1, * "min_processing_days": 0, * "max_processing_days": 0, * "shipping_method": "string", * "shipping_upgrade": "string", * "expected_ship_date": 946684800, * "buyer_coupon": 0, * "shop_coupon": 0 } ] }` [](https://developers.etsy.com/documentation/reference#tag/Review) Review ========================================================================= [](https://developers.etsy.com/documentation/reference#operation/getReviewsByListing) getReviewsByListing --------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 to retrieve the reviews for a listing given its ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | listing\_id

required | integer \>= 1

The numeric ID for the [listing](https://developers.etsy.com/documentation/reference#tag/ShopListing)
associated to this transaction. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | min\_created | integer \>= 946684800 Nullable

The earliest unix timestamp for when a record was created. | | max\_created | integer \>= 946684800 Nullable

The latest unix timestamp for when a record was created. | ### Responses **200** A set of Transaction Reviews by Listing ID **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/listings/{listing\_id}/reviews Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/listings/{listing\_id}/reviews ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shop_id": 1, * "listing_id": 1, * "rating": 1, * "review": "string", * "language": "string", * "image_url_fullxfull": "string", * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800 } ] }` [](https://developers.etsy.com/documentation/reference#operation/getReviewsByShop) getReviewsByShop --------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 to retrieve the reviews from a shop given its ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | | min\_created | integer \>= 946684800 Nullable

The earliest unix timestamp for when a record was created. | | max\_created | integer \>= 946684800 Nullable

The latest unix timestamp for when a record was created. | ### Responses **200** A set of Transaction Reviews By Shop ID **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/reviews Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/reviews ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shop_id": 1, * "listing_id": 1, * "transaction_id": 1, * "buyer_user_id": 1, * "rating": 1, * "review": "", * "language": "string", * "image_url_fullxfull": "string", * "create_timestamp": 946684800, * "created_timestamp": 946684800, * "update_timestamp": 946684800, * "updated_timestamp": 946684800 } ] }` [](https://developers.etsy.com/documentation/reference#tag/Shop-HolidayPreferences) Shop HolidayPreferences =========================================================================================================== [](https://developers.etsy.com/documentation/reference#operation/getHolidayPreferences) getHolidayPreferences ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of holidays that are available to a shop to set a preference for. Currently only supported in the US and CA ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ### Responses **200** A list of holiday preferences **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/holiday-preferences Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/holiday-preferences ### Response samples * 200 * 400 * 403 * 500 Content type application/json Copy Expand all Collapse all `[ * { * "shop_id": 1, * "holiday_id": 1, * "country_iso": "string", * "is_working": true, * "holiday_name": "string" } ]` [](https://developers.etsy.com/documentation/reference#operation/updateHolidayPreferences) updateHolidayPreferences ------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates the preference for whether the seller will process orders or not on the holiday. Currently only supported in the US and CA ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | holiday\_id

required | integer

Enum: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

The unique id that maps to the holiday a country observes. See the [Fulfillment Tutorial docs](https://developer.etsy.com/documentation/tutorials/fulfillment/#country-holidays)
for more info | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | is\_working

required | boolean

A boolean value for whether the shop will process orders on a particular holiday. | ### Responses **200** The updated holiday preferences **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. put/v3/application/shops/{shop\_id}/holiday-preferences/{holiday\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/holiday-preferences/{holiday\_id} ### Response samples * 200 * 400 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "shop_id": 1, * "holiday_id": 1, * "country_iso": "string", * "is_working": true, * "holiday_name": "string" }` [](https://developers.etsy.com/documentation/reference#tag/Shop-ProcessingProfiles) Shop ProcessingProfiles =========================================================================================================== [](https://developers.etsy.com/documentation/reference#operation/createShopReadinessStateDefinition) createShopReadinessStateDefinition --------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates a new ReadinessStateDefinition. If an existing definition matches the input values, this endpoint will throw a Conflict error, please refer to the Content-Location header to obtain the get endpoint url for the values of the existing definition. Does not affect the product offering-readiness states definition relationship. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | readiness\_state

required | string

Enum: "ready\_to\_ship" "made\_to\_order"

The readiness state of a product: "1" means "ready\_to\_ship", and "2" means "made\_to\_order" | | min\_processing\_time

required | integer \[ 1 .. 10 \]

The minimum number of days or weeks for processing a specific product. | | max\_processing\_time

required | integer \[ 1 .. 10 \]

The maximum number of days or weeks for processing a specific product. | | processing\_time\_unit | string

Default: "days"

Enum: "days" "weeks"

The unit used to represent how long a processing time is. A week is equivalent to how many days the seller works per week as stated in their processing schedule. If none is provided, the unit is set to "days". | ### Responses **201** A single ReadinessStateDefinition **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/readiness-state-definitions Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/readiness-state-definitions ### Response samples * 201 * 400 * 401 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "shop_id": 1, * "readiness_state_id": 1, * "readiness_state": "ready_to_ship", * "min_processing_days": 0, * "max_processing_days": 0, * "processing_days_display_label": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinitions) getShopReadinessStateDefinitions ----------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of ProcessingProfiles available in the specific Etsy shop identified by its shop ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | ### Responses **200** A list of ProcessingProfiles **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/readiness-state-definitions Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/readiness-state-definitions ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shop_id": 1, * "readiness_state_id": 1, * "readiness_state": "ready_to_ship", * "min_processing_days": 0, * "max_processing_days": 0, * "processing_days_display_label": "string" } ] }` [](https://developers.etsy.com/documentation/reference#operation/deleteShopReadinessStateDefinition) deleteShopReadinessStateDefinition --------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes a ReadinessStateDefinition by given readiness state definition ID. If there any active offerings linked to the definition, this endpoint will throw a Bad Request error. If you want to delete a ReadinessStateDefinition that is linked to active offerings, you must link the offerings to a different readiness state definition. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | readiness\_state\_definition\_id

required | integer \>= 1

The numeric ID of the [processing profile](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinition)
associated with the listing. Returned only when the listing is `active` and of type `physical`, and the endpoint is either shop-scoped (path contains `shop_id`) or a single-listing request such as `getListing`. For every other case this field can be null. | ### Responses **204** The ReadinessStateDefinition was successfully deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/readiness-state-definitions/{readiness\_state\_definition\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/readiness-state-definitions/{readiness\_state\_definition\_id} ### Response samples * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinition) getShopReadinessStateDefinition --------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a ProcessingProfile referenced by readiness state definition ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | readiness\_state\_definition\_id

required | integer \>= 1

The numeric ID of the [processing profile](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinition)
associated with the listing. Returned only when the listing is `active` and of type `physical`, and the endpoint is either shop-scoped (path contains `shop_id`) or a single-listing request such as `getListing`. For every other case this field can be null. | ### Responses **200** A single ProcessingProfile **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/readiness-state-definitions/{readiness\_state\_definition\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/readiness-state-definitions/{readiness\_state\_definition\_id} ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "shop_id": 1, * "readiness_state_id": 1, * "readiness_state": "ready_to_ship", * "min_processing_days": 0, * "max_processing_days": 0, * "processing_days_display_label": "string" }` [](https://developers.etsy.com/documentation/reference#operation/updateShopReadinessStateDefinition) updateShopReadinessStateDefinition --------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates an existing ReadinessStateDefinition. If an existing definition matches the input values, this endpoint will throw a Conflict error, please refer to the Content-Location header to obtain the get endpoint url for the values of the existing definition. Does not affect the product offering-readiness states definition relationship. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | readiness\_state\_definition\_id

required | integer \>= 1

The numeric ID of the [processing profile](https://developers.etsy.com/documentation/reference#operation/getShopReadinessStateDefinition)
associated with the listing. Returned only when the listing is `active` and of type `physical`, and the endpoint is either shop-scoped (path contains `shop_id`) or a single-listing request such as `getListing`. For every other case this field can be null. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | readiness\_state | string

Enum: "ready\_to\_ship" "made\_to\_order"

The readiness state of a product: "1" means "ready\_to\_ship", and "2" means "made\_to\_order" | | min\_processing\_time | integer \[ 1 .. 10 \]

The minimum number of days or weeks for processing a specific product. | | max\_processing\_time | integer \[ 1 .. 10 \]

The maximum number of days or weeks for processing a specific product. | | processing\_time\_unit | string

Default: "days"

Enum: "days" "weeks"

The unit used to represent how long a processing time is. A week is equivalent to how many days the seller works per week as stated in their processing schedule. If none is provided, the unit is set to "days". | ### Responses **200** The updated ReadinessStateDefinition **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. put/v3/application/shops/{shop\_id}/readiness-state-definitions/{readiness\_state\_definition\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/readiness-state-definitions/{readiness\_state\_definition\_id} ### Response samples * 200 * 400 * 401 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "shop_id": 1, * "readiness_state_id": 1, * "readiness_state": "ready_to_ship", * "min_processing_days": 0, * "max_processing_days": 0, * "processing_days_display_label": "string" }` [](https://developers.etsy.com/documentation/reference#tag/Shop-ShippingProfile) Shop ShippingProfile ===================================================================================================== [](https://developers.etsy.com/documentation/reference#operation/getShippingCarriers) getShippingCarriers --------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of available shipping carriers and the mail classes associated with them for a given country ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### query Parameters | | | | --- | --- | | origin\_country\_iso

required | string

The ISO code of the country from which the listing ships. | ### Responses **200** A set of ShippingCarriers **400** There was a problem with the request data. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shipping-carriers Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shipping-carriers ### Response samples * 200 * 400 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shipping_carrier_id": 1, * "name": "string", * "domestic_classes": [ * { * "mail_class_key": "string", * "name": "string" } ], * "international_classes": [ * { * "mail_class_key": "string", * "name": "string" } ] } ] }` [](https://developers.etsy.com/documentation/reference#operation/createShopShippingProfile) createShopShippingProfile --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates a new ShippingProfile. You can pass a country iso code or a region when creating a ShippingProfile, but not both. Only one is required. You must pass either a shipping\_carrier\_id AND mail\_class, or both min and max\_delivery\_days. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | title

required | string

The name string of this shipping profile. | | origin\_country\_iso

required | string

The ISO code of the country from which the listing ships. | | primary\_cost

required | number \>= 0

The cost of shipping to this country/region alone, measured in the store's default currency. | | secondary\_cost

required | number \>= 0

The cost of shipping to this country/region with another item, measured in the store's default currency. | | min\_processing\_time | integer \[ 1 .. 10 \]

The minimum time required to process to ship listings with this shipping profile. | | max\_processing\_time | integer \[ 1 .. 10 \]

The maximum processing time the listing needs to ship. | | processing\_time\_unit | string

Default: "business\_days"

Enum: "business\_days" "weeks"

The unit used to represent how long a processing time is. A week is equivalent to the set processing schedule (default to 5 business days). If none is provided, the unit is set to "business\_days". | | destination\_country\_iso | string

Default: null

The ISO code of the country to which the listing ships. If null, request sets destination to destination\_region. Required if destination\_region is null or not provided. | | destination\_region | string

Default: "none"

Enum: "eu" "non\_eu" "none"

The code of the region to which the listing ships. A region represents a set of countries. Supported regions are Europe Union and Non-Europe Union (countries in Europe not in EU). If `none`, request sets destination to destination\_country\_iso. Required if destination\_country\_iso is null or not provided. | | origin\_postal\_code | string

Default: ""

The postal code string (not necessarily a number) for the location from which the listing ships. Required if the `origin_country_iso` supports postal codes. See the [Fulfillment Tutorial docs](https://developer.etsy.com/documentation/tutorials/fulfillment/#countries-requiring-postal-codes)
for more info | | shipping\_carrier\_id | integer \>= 0

Default: 0

The unique ID of a supported shipping carrier, which is used to calculate an Estimated Delivery Date. **Required with `mail_class`** if `min_delivery_days` and `max_delivery_days` are null. | | mail\_class | string

Default: null

The unique ID string of a shipping carrier's mail class, which is used to calculate an estimated delivery date. **Required with `shipping_carrier_id`** if `min_delivery_days` and `max_delivery_days` are null. | | min\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The minimum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `max_delivery_days`** if `mail_class` is null. | | max\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The maximum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `min_delivery_days`** if `mail_class` is null. | ### Responses **200** A single ShippingProfile **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/shipping-profiles Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles ### Response samples * 200 * 400 * 401 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "shipping_profile_id": 1, * "title": "string", * "user_id": 1, * "origin_country_iso": "string", * "is_deleted": true, * "shipping_profile_destinations": [ * { * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "shipping_profile_upgrades": [ * { * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "origin_postal_code": "string", * "profile_type": "manual", * "domestic_handling_fee": 0, * "international_handling_fee": 0 }` [](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfiles) getShopShippingProfiles ----------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of shipping profiles available in the specific Etsy shop identified by its shop ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ### Responses **200** A list of shipping profiles **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/shipping-profiles Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles ### Response samples * 200 * 400 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shipping_profile_id": 1, * "title": "string", * "user_id": 1, * "origin_country_iso": "string", * "is_deleted": true, * "shipping_profile_destinations": [ * { * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "shipping_profile_upgrades": [ * { * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "origin_postal_code": "string", * "profile_type": "manual", * "domestic_handling_fee": 0, * "international_handling_fee": 0 } ] }` [](https://developers.etsy.com/documentation/reference#operation/deleteShopShippingProfile) deleteShopShippingProfile --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes a ShippingProfile by given id. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | ### Responses **204** The ShopShippingProfile resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id} ### Response samples * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile) getShopShippingProfile --------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a Shipping Profile referenced by shipping profile ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | ### Responses **200** A single ShippingProfile **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "shipping_profile_id": 1, * "title": "string", * "user_id": 1, * "origin_country_iso": "string", * "is_deleted": true, * "shipping_profile_destinations": [ * { * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "shipping_profile_upgrades": [ * { * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "origin_postal_code": "string", * "profile_type": "manual", * "domestic_handling_fee": 0, * "international_handling_fee": 0 }` [](https://developers.etsy.com/documentation/reference#operation/updateShopShippingProfile) updateShopShippingProfile --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Changes the settings in a shipping profile. You can pass a country iso code or a region when updating a ShippingProfile, but not both. Only one is required. You must pass either a shipping\_carrier\_id AND mail\_class, or both min and max\_delivery\_days. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | title | string

The name string of this shipping profile. | | origin\_country\_iso | string

The ISO code of the country from which the listing ships. | | min\_processing\_time | integer \[ 1 .. 10 \]

The minimum time required to process to ship listings with this shipping profile. | | max\_processing\_time | integer \[ 1 .. 10 \]

The maximum processing time the listing needs to ship. | | processing\_time\_unit | string

Default: "business\_days"

Enum: "business\_days" "weeks"

The unit used to represent how long a processing time is. A week is equivalent to the set processing schedule (default to 5 business days). If none is provided, the unit is set to "business\_days". | | origin\_postal\_code | string

Default: null

The postal code string (not necessarily a number) for the location from which the listing ships. Required if the `origin_country_iso` supports postal codes. See the [Fulfillment Tutorial docs](https://developer.etsy.com/documentation/tutorials/fulfillment/#countries-requiring-postal-codes)
for more info | ### Responses **200** The updated shipping profile. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. **503** This function is temporarily unavailable. Please try again later. put/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 * 503 Content type application/json Copy Expand all Collapse all `{ * "shipping_profile_id": 1, * "title": "string", * "user_id": 1, * "origin_country_iso": "string", * "is_deleted": true, * "shipping_profile_destinations": [ * { * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "shipping_profile_upgrades": [ * { * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ], * "origin_postal_code": "string", * "profile_type": "manual", * "domestic_handling_fee": 0, * "international_handling_fee": 0 }` [](https://developers.etsy.com/documentation/reference#operation/createShopShippingProfileDestination) createShopShippingProfileDestination ------------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates a new shipping destination, which sets the shipping cost, carrier, and class for a destination in a [shipping profile](https://developers.etsy.com/documentation/reference/#tag/Shop-ShippingProfile) . createShopShippingProfileDestination assigns costs using the currency of the associated shop. Set the destination using either `destination_country_iso` or `destination_region`; `destination_country_iso` and `destination_region` are mutually exclusive — set one or the other. Setting both triggers error 400. If the request sets neither `destination_country_iso` nor `destination_region`, the default destination is "everywhere". You must also either assign both a `shipping_carrier_id` AND `mail_class` or both `min_delivery_days` AND `max_delivery_days`. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | primary\_cost

required | number \>= 0

The cost of shipping to this country/region alone, measured in the store's default currency. | | secondary\_cost

required | number \>= 0

The cost of shipping to this country/region with another item, measured in the store's default currency. | | destination\_country\_iso | string

Default: null

The ISO code of the country to which the listing ships. If null, request sets destination to destination\_region. Required if destination\_region is null or not provided. | | destination\_region | string

Default: "none"

Enum: "eu" "non\_eu" "none"

The code of the region to which the listing ships. A region represents a set of countries. Supported regions are Europe Union and Non-Europe Union (countries in Europe not in EU). If `none`, request sets destination to destination\_country\_iso. Required if destination\_country\_iso is null or not provided. | | shipping\_carrier\_id | integer \>= 0

Default: 0

The unique ID of a supported shipping carrier, which is used to calculate an Estimated Delivery Date. **Required with `mail_class`** if `min_delivery_days` and `max_delivery_days` are null. | | mail\_class | string

Default: null

The unique ID string of a shipping carrier's mail class, which is used to calculate an estimated delivery date. **Required with `shipping_carrier_id`** if `min_delivery_days` and `max_delivery_days` are null. | | min\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The minimum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `max_delivery_days`** if `mail_class` is null. | | max\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The maximum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `min_delivery_days`** if `mail_class` is null. | ### Responses **201** A single shipping destination. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/destinations Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/destinations ### Response samples * 201 * 400 * 401 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 }` [](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfileDestinationsByShippingProfile) getShopShippingProfileDestinationsByShippingProfile ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of shipping destination objects associated with a shipping profile. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | ### Responses **200** A list of shipping destination objects. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/destinations Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/destinations ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ] }` [](https://developers.etsy.com/documentation/reference#operation/deleteShopShippingProfileDestination) deleteShopShippingProfileDestination ------------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes a shipping destination and removes the destination option from every listing that uses the associated shipping profile. A shipping profile requires at least one shipping destination, so this endpoint cannot delete the final shipping destination for any shipping profile. To delete the final shipping destination from a shipping profile, you must [delete the entire shipping profile](https://developers.etsy.com/documentation/reference/#operation/deleteShopShippingProfile) . ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | | shipping\_profile\_destination\_id

required | integer \>= 1

The numeric ID of the shipping profile destination in the [shipping profile](https://developers.etsy.com/documentation/reference#tag/Shop-ShippingProfile)
associated with the listing. | ### Responses **204** Etsy deleted the shipping profile destination. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/destinations/{shipping\_profile\_destination\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/destinations/{shipping\_profile\_destination\_id} ### Response samples * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/updateShopShippingProfileDestination) updateShopShippingProfileDestination ------------------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates an existing shipping destination, which can set or reassign the shipping cost, carrier, and class for a destination. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | | shipping\_profile\_destination\_id

required | integer \>= 1

The numeric ID of the shipping profile destination in the [shipping profile](https://developers.etsy.com/documentation/reference#tag/Shop-ShippingProfile)
associated with the listing. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | primary\_cost | number \>= 0

Default: null

The cost of shipping to this country/region alone, measured in the store's default currency. | | secondary\_cost | number \>= 0

Default: null

The cost of shipping to this country/region with another item, measured in the store's default currency. | | destination\_country\_iso | string

Default: null

The ISO code of the country to which the listing ships. If null, request sets destination to destination\_region. Required if destination\_region is null or not provided. | | destination\_region | string

Default: "none"

Enum: "eu" "non\_eu" "none"

The code of the region to which the listing ships. A region represents a set of countries. Supported regions are Europe Union and Non-Europe Union (countries in Europe not in EU). If `none`, request sets destination to destination\_country\_iso. Required if destination\_country\_iso is null or not provided. | | shipping\_carrier\_id | integer \>= 0

Default: null

The unique ID of a supported shipping carrier, which is used to calculate an Estimated Delivery Date. **Required with `mail_class`** if `min_delivery_days` and `max_delivery_days` are null. | | mail\_class | string

Default: null

The unique ID string of a shipping carrier's mail class, which is used to calculate an estimated delivery date. **Required with `shipping_carrier_id`** if `min_delivery_days` and `max_delivery_days` are null. | | min\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The minimum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `max_delivery_days`** if `mail_class` is null. | | max\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The maximum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `min_delivery_days`** if `mail_class` is null. | ### Responses **200** A single shipping destination. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. **503** This function is temporarily unavailable. Please try again later. put/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/destinations/{shipping\_profile\_destination\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/destinations/{shipping\_profile\_destination\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 * 503 Content type application/json Copy Expand all Collapse all `{ * "shipping_profile_destination_id": 1, * "shipping_profile_id": 1, * "origin_country_iso": "string", * "destination_country_iso": "string", * "destination_region": "eu", * "primary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_cost": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 }` [](https://developers.etsy.com/documentation/reference#operation/createShopShippingProfileUpgrade) createShopShippingProfileUpgrade ----------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates a new shipping profile upgrade, which can establish a price for a shipping option, such as an alternate carrier or faster delivery. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | type

required | integer

Enum: 0 1

The type of the shipping upgrade. Domestic (0) or international (1). | | upgrade\_name

required | string

Name for the shipping upgrade shown to shoppers at checkout, e.g. USPS Priority. | | price

required | number \>= 0

Additional cost of adding the shipping upgrade. | | secondary\_price

required | number \>= 0

Additional cost of adding the shipping upgrade for each additional item. | | shipping\_carrier\_id | integer \>= 0

Default: 0

The unique ID of a supported shipping carrier, which is used to calculate an Estimated Delivery Date. **Required with `mail_class`** if `min_delivery_days` and `max_delivery_days` are null. | | mail\_class | string

Default: null

The unique ID string of a shipping carrier's mail class, which is used to calculate an estimated delivery date. **Required with `shipping_carrier_id`** if `min_delivery_days` and `max_delivery_days` are null. | | min\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The minimum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `max_delivery_days`** if `mail_class` is null. | | max\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The maximum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `min_delivery_days`** if `mail_class` is null. | ### Responses **200** A single shipping profile upgrade. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/upgrades Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/upgrades ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 }` [](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfileUpgrades) getShopShippingProfileUpgrades ------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the list of shipping profile upgrades assigned to a specific shipping profile. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | ### Responses **200** A list of shipping profile upgrades. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/upgrades Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/upgrades ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 } ] }` [](https://developers.etsy.com/documentation/reference#operation/deleteShopShippingProfileUpgrade) deleteShopShippingProfileUpgrade ----------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes a shipping profile upgrade and removes the upgrade option from every listing that uses the associated shipping profile. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the shipping profile. | | upgrade\_id

required | integer \>= 1

The numeric ID that is associated with a shipping upgrade | ### Responses **204** Etsy deleted the shipping profile upgrade. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/upgrades/{upgrade\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/upgrades/{upgrade\_id} ### Response samples * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/updateShopShippingProfileUpgrade) updateShopShippingProfileUpgrade ----------------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates a shipping profile upgrade and updates any listings that use the shipping profile. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shipping\_profile\_id

required | integer \>= 1

The numeric ID of the [shipping profile](https://developers.etsy.com/documentation/reference#operation/getShopShippingProfile)
associated with the listing. Required when listing type is `physical`. | | upgrade\_id

required | integer \>= 1

The numeric ID that is associated with a shipping upgrade | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | upgrade\_name | string

Default: null

Name for the shipping upgrade shown to shoppers at checkout, e.g. USPS Priority. | | type | integer

Enum: 0 1

The type of the shipping upgrade. Domestic (0) or international (1). | | price | number \>= 0

Default: null

Additional cost of adding the shipping upgrade. | | secondary\_price | number \>= 0

Default: null

Additional cost of adding the shipping upgrade for each additional item. | | shipping\_carrier\_id | integer \>= 0

Default: null

The unique ID of a supported shipping carrier, which is used to calculate an Estimated Delivery Date. **Required with `mail_class`** if `min_delivery_days` and `max_delivery_days` are null. | | mail\_class | string

Default: null

The unique ID string of a shipping carrier's mail class, which is used to calculate an estimated delivery date. **Required with `shipping_carrier_id`** if `min_delivery_days` and `max_delivery_days` are null. | | min\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The minimum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `max_delivery_days`** if `mail_class` is null. | | max\_delivery\_days | integer \[ 1 .. 45 \]

Default: null

The maximum number of business days a buyer can expect to wait to receive their purchased item once it has shipped. **Required with `min_delivery_days`** if `mail_class` is null. | ### Responses **200** A single shipping profile upgrade. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. **503** This function is temporarily unavailable. Please try again later. put/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/upgrades/{upgrade\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/shipping-profiles/{shipping\_profile\_id}/upgrades/{upgrade\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 * 503 Content type application/json Copy Expand all Collapse all `{ * "shipping_profile_id": 1, * "upgrade_id": 1, * "upgrade_name": "string", * "type": 0, * "rank": 0, * "language": "string", * "price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "secondary_price": { * "amount": 0, * "divisor": 0, * "currency_code": "string" }, * "shipping_carrier_id": 0, * "mail_class": "string", * "min_delivery_days": 1, * "max_delivery_days": 1 }` [](https://developers.etsy.com/documentation/reference#tag/Shop) Shop ===================================================================== [](https://developers.etsy.com/documentation/reference#operation/getShop) getShop --------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the shop identified by a specific shop ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ### Responses **200** A single Shop **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id} ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "shop_id": 1, * "user_id": 1, * "shop_name": "string", * "create_date": 0, * "created_timestamp": 0, * "title": "string", * "announcement": "string", * "currency_code": "string", * "is_vacation": true, * "vacation_message": "string", * "sale_message": "string", * "digital_sale_message": "string", * "update_date": 0, * "updated_timestamp": 0, * "listing_active_count": 0, * "digital_listing_count": 0, * "login_name": "string", * "accepts_custom_requests": true, * "policy_welcome": "string", * "policy_payment": "string", * "policy_shipping": "string", * "policy_refunds": "string", * "policy_additional": "string", * "policy_seller_info": "string", * "policy_update_date": 0, * "policy_has_private_receipt_info": true, * "has_unstructured_policies": true, * "policy_privacy": "string", * "vacation_autoreply": "string", * "url": "string", * "image_url_760x100": "string", * "num_favorers": 0, * "languages": [ * "string" ], * "icon_url_fullxfull": "string", * "is_using_structured_policies": true, * "has_onboarded_structured_policies": true, * "include_dispute_form_link": true, * "is_direct_checkout_onboarded": true, * "is_etsy_payments_onboarded": true, * "is_calculated_eligible": true, * "is_opted_in_to_buyer_promise": true, * "is_shop_us_based": true, * "transaction_sold_count": 0, * "shipping_from_country_iso": "string", * "shop_location_country_iso": "string", * "review_count": 0, * "review_average": 0 }` [](https://developers.etsy.com/documentation/reference#operation/updateShop) updateShop --------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates a shop. Assumes that all string parameters are provided in the shop's primary language. Please note that the policy\_additional field should only be set for shops located in the EU. Passing a value for this field for shops outside of the EU, will result in an error. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r``shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | title | string

A brief heading string for the shop's main page. | | announcement | string

An announcement string to buyers that displays on the shop's homepage. | | sale\_message | string

A message string sent to users who complete a purchase from this shop. | | digital\_sale\_message | string

A message string sent to users who purchase a digital item from this shop. | | policy\_additional | string

The shop's additional policies string (may be blank). | ### Responses **200** A single Shop. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. put/v3/application/shops/{shop\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "shop_id": 1, * "user_id": 1, * "shop_name": "string", * "create_date": 0, * "created_timestamp": 0, * "title": "string", * "announcement": "string", * "currency_code": "string", * "is_vacation": true, * "vacation_message": "string", * "sale_message": "string", * "digital_sale_message": "string", * "update_date": 0, * "updated_timestamp": 0, * "listing_active_count": 0, * "digital_listing_count": 0, * "login_name": "string", * "accepts_custom_requests": true, * "policy_welcome": "string", * "policy_payment": "string", * "policy_shipping": "string", * "policy_refunds": "string", * "policy_additional": "string", * "policy_seller_info": "string", * "policy_update_date": 0, * "policy_has_private_receipt_info": true, * "has_unstructured_policies": true, * "policy_privacy": "string", * "vacation_autoreply": "string", * "url": "string", * "image_url_760x100": "string", * "num_favorers": 0, * "languages": [ * "string" ], * "icon_url_fullxfull": "string", * "is_using_structured_policies": true, * "has_onboarded_structured_policies": true, * "include_dispute_form_link": true, * "is_direct_checkout_onboarded": true, * "is_etsy_payments_onboarded": true, * "is_calculated_eligible": true, * "is_opted_in_to_buyer_promise": true, * "is_shop_us_based": true, * "transaction_sold_count": 0, * "shipping_from_country_iso": "string", * "shop_location_country_iso": "string", * "review_count": 0, * "review_average": 0 }` [](https://developers.etsy.com/documentation/reference#operation/getShopByOwnerUserId) getShopByOwnerUserId ----------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the shop identified by the shop owner's user ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | user\_id

required | integer \>= 1

The numeric user ID of the [user](https://developers.etsy.com/documentation/reference#tag/User)
who owns this shop. | ### Responses **200** A single Shop **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/users/{user\_id}/shops Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/users/{user\_id}/shops ### Response samples * 200 * 400 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "shop_id": 1, * "user_id": 1, * "shop_name": "string", * "create_date": 0, * "created_timestamp": 0, * "title": "string", * "announcement": "string", * "currency_code": "string", * "is_vacation": true, * "vacation_message": "string", * "sale_message": "string", * "digital_sale_message": "string", * "update_date": 0, * "updated_timestamp": 0, * "listing_active_count": 0, * "digital_listing_count": 0, * "login_name": "string", * "accepts_custom_requests": true, * "policy_welcome": "string", * "policy_payment": "string", * "policy_shipping": "string", * "policy_refunds": "string", * "policy_additional": "string", * "policy_seller_info": "string", * "policy_update_date": 0, * "policy_has_private_receipt_info": true, * "has_unstructured_policies": true, * "policy_privacy": "string", * "vacation_autoreply": "string", * "url": "string", * "image_url_760x100": "string", * "num_favorers": 0, * "languages": [ * "string" ], * "icon_url_fullxfull": "string", * "is_using_structured_policies": true, * "has_onboarded_structured_policies": true, * "include_dispute_form_link": true, * "is_direct_checkout_onboarded": true, * "is_etsy_payments_onboarded": true, * "is_calculated_eligible": true, * "is_opted_in_to_buyer_promise": true, * "is_shop_us_based": true, * "transaction_sold_count": 0, * "shipping_from_country_iso": "string", * "shop_location_country_iso": "string", * "review_count": 0, * "review_average": 0 }` [](https://developers.etsy.com/documentation/reference#operation/findShops) findShops ------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 endpoint for searching shops by name. Note: We make every effort to ensure that frozen or removed shops are not included in the search results. However, rarely, due to timing issues, they may appear. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### query Parameters | | | | --- | --- | | shop\_name

required | string

The shop's name string. | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | ### Responses **200** A list of Shops **500** The server encountered an internal error. See the error message for details. get/v3/application/shops Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops ### Response samples * 200 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shop_id": 1, * "user_id": 1, * "shop_name": "string", * "create_date": 0, * "created_timestamp": 0, * "title": "string", * "announcement": "string", * "currency_code": "string", * "is_vacation": true, * "vacation_message": "string", * "sale_message": "string", * "digital_sale_message": "string", * "update_date": 0, * "updated_timestamp": 0, * "listing_active_count": 0, * "digital_listing_count": 0, * "login_name": "string", * "accepts_custom_requests": true, * "policy_welcome": "string", * "policy_payment": "string", * "policy_shipping": "string", * "policy_refunds": "string", * "policy_additional": "string", * "policy_seller_info": "string", * "policy_update_date": 0, * "policy_has_private_receipt_info": true, * "has_unstructured_policies": true, * "policy_privacy": "string", * "vacation_autoreply": "string", * "url": "string", * "image_url_760x100": "string", * "num_favorers": 0, * "languages": [ * "string" ], * "icon_url_fullxfull": "string", * "is_using_structured_policies": true, * "has_onboarded_structured_policies": true, * "include_dispute_form_link": true, * "is_direct_checkout_onboarded": true, * "is_etsy_payments_onboarded": true, * "is_calculated_eligible": true, * "is_opted_in_to_buyer_promise": true, * "is_shop_us_based": true, * "transaction_sold_count": 0, * "shipping_from_country_iso": "string", * "shop_location_country_iso": "string", * "review_count": 0, * "review_average": 0 } ] }` [](https://developers.etsy.com/documentation/reference#tag/Shop-ProductionPartner) Shop ProductionPartner ========================================================================================================= [](https://developers.etsy.com/documentation/reference#operation/getShopProductionPartners) getShopProductionPartners --------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a list of production partners available in the specific Etsy shop identified by its shop ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ### Responses **200** A list of shop production partners **400** There was a problem with the request data. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/production-partners Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/production-partners ### Response samples * 200 * 400 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "production_partner_id": 1, * "partner_name": "string", * "location": "string" } ] }` [](https://developers.etsy.com/documentation/reference#tag/Shop-Section) Shop Section ===================================================================================== [](https://developers.etsy.com/documentation/reference#operation/createShopSection) createShopSection ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates a new section in a specific shop. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | title

required | string

The title string for a shop section. | ### Responses **200** A Shop Section resource **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. **503** This function is temporarily unavailable. Please try again later. post/v3/application/shops/{shop\_id}/sections Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/sections ### Response samples * 200 * 400 * 401 * 403 * 500 * 503 Content type application/json Copy Expand all Collapse all `{ * "shop_section_id": 1, * "title": "string", * "rank": 0, * "user_id": 1, * "active_listing_count": 0 }` [](https://developers.etsy.com/documentation/reference#operation/getShopSections) getShopSections ------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves the list of shop sections in a specific shop identified by shop ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ### Responses **200** A list of shop sections. **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/sections Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/sections ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "shop_section_id": 1, * "title": "string", * "rank": 0, * "user_id": 1, * "active_listing_count": 0 } ] }` [](https://developers.etsy.com/documentation/reference#operation/deleteShopSection) deleteShopSection ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes a section in a specific shop given a valid shop\_section\_id. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shop\_section\_id

required | integer \>= 1

The numeric ID of a section in a specific Etsy shop. | ### Responses **204** The shop section resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. **503** This function is temporarily unavailable. Please try again later. delete/v3/application/shops/{shop\_id}/sections/{shop\_section\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/sections/{shop\_section\_id} ### Response samples * 400 * 401 * 403 * 500 * 503 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getShopSection) getShopSection ----------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a shop section, referenced by section ID and shop ID. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shop\_section\_id

required | integer \>= 1

The numeric ID of a section in a specific Etsy shop. | ### Responses **200** A shop section resource **400** There was a problem with the request data. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/sections/{shop\_section\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/sections/{shop\_section\_id} ### Response samples * 200 * 400 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "shop_section_id": 1, * "title": "string", * "rank": 0, * "user_id": 1, * "active_listing_count": 0 }` [](https://developers.etsy.com/documentation/reference#operation/updateShopSection) updateShopSection ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates a section in a specific shop given a valid shop\_section\_id. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | shop\_section\_id

required | integer \>= 1

The numeric ID of a section in a specific Etsy shop. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | title

required | string

The title string for a shop section. | ### Responses **200** A Shop Section resource **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. **503** This function is temporarily unavailable. Please try again later. put/v3/application/shops/{shop\_id}/sections/{shop\_section\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/sections/{shop\_section\_id} ### Response samples * 200 * 400 * 401 * 403 * 500 * 503 Content type application/json Copy Expand all Collapse all `{ * "shop_section_id": 1, * "title": "string", * "rank": 0, * "user_id": 1, * "active_listing_count": 0 }` [](https://developers.etsy.com/documentation/reference#tag/Shop-Return-Policy) Shop Return Policy ================================================================================================= [](https://developers.etsy.com/documentation/reference#operation/consolidateShopReturnPolicies) consolidateShopReturnPolicies ----------------------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Consolidates Return Policies by moving all listings from a source return policy to a destination return policy, and deleting the source return policy. This is commonly used in the event that a user attempts to update a Return Policy such that its data is a duplicate of some other Return Policy, which is prevented. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | source\_return\_policy\_id

required | integer \>= 1

The numeric ID of the [Return Policy](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies)
. | | destination\_return\_policy\_id

required | integer \>= 1

The numeric ID of the [Return Policy](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies)
. | ### Responses **200** The updated target Return Policy **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/policies/return/consolidate Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/policies/return/consolidate ### Response samples * 200 * 400 * 401 * 403 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "return_policy_id": 1, * "shop_id": 1, * "accepts_returns": true, * "accepts_exchanges": true, * "return_deadline": 0 }` [](https://developers.etsy.com/documentation/reference#operation/createShopReturnPolicy) createShopReturnPolicy --------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Creates a new Return Policy. Note: if either accepts\_returns or accepts\_exchanges is true, then a return\_deadline is required. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | accepts\_returns

required | boolean | | accepts\_exchanges

required | boolean | | return\_deadline | integer Nullable

The deadline for the Return Policy, measured in days. The value must be one of the following: \[7, 14, 21, 30, 45, 60, 90\]. | ### Responses **200** A single Return Policy **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. post/v3/application/shops/{shop\_id}/policies/return Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/policies/return ### Response samples * 200 * 400 * 401 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "return_policy_id": 1, * "shop_id": 1, * "accepts_returns": true, * "accepts_exchanges": true, * "return_deadline": 0 }` [](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies) getShopReturnPolicies ------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Returns a shop's list of existing Return Policies ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | ### Responses **200** List of shop's Return Policies **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/policies/return Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/policies/return ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "return_policy_id": 1, * "shop_id": 1, * "accepts_returns": true, * "accepts_exchanges": true, * "return_deadline": 0 } ] }` [](https://developers.etsy.com/documentation/reference#operation/deleteShopReturnPolicy) deleteShopReturnPolicy --------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Deletes an existing Return Policy. Deletion is only allowed for policies which have no associated listings – move them to another policy before attempting deletion. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | return\_policy\_id

required | integer \>= 1

The numeric ID of the [Return Policy](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies)
. | ### Responses **204** The Return Policy was successfully deleted. **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/shops/{shop\_id}/policies/return/{return\_policy\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/policies/return/{return\_policy\_id} ### Response samples * 400 * 401 * 403 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicy) getShopReturnPolicy --------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves an existing Return Policy. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | return\_policy\_id

required | integer \>= 1

The numeric ID of the [Return Policy](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies)
. | ### Responses **200** A single Return Policy **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/shops/{shop\_id}/policies/return/{return\_policy\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/policies/return/{return\_policy\_id} ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "return_policy_id": 1, * "shop_id": 1, * "accepts_returns": true, * "accepts_exchanges": true, * "return_deadline": 0 }` [](https://developers.etsy.com/documentation/reference#operation/updateShopReturnPolicy) updateShopReturnPolicy --------------------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Updates an existing Return Policy. Note: if either accepts\_returns or accepts\_exchanges is true, then a return\_deadline is required. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_w`) ##### path Parameters | | | | --- | --- | | shop\_id

required | integer \>= 1

The unique positive non-zero numeric ID for an Etsy Shop. | | return\_policy\_id

required | integer \>= 1

The numeric ID of the [Return Policy](https://developers.etsy.com/documentation/reference#operation/getShopReturnPolicies)
. | ##### Request Body schema: application/x-www-form-urlencoded | | | | --- | --- | | accepts\_returns

required | boolean | | accepts\_exchanges

required | boolean | | return\_deadline | integer Nullable

The deadline for the Return Policy, measured in days. The value must be one of the following: \[7, 14, 21, 30, 45, 60, 90\]. | ### Responses **200** An updated Return Policy **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **403** The request attempted to perform an operation it is not allowed to. See the error message for details. **404** A resource could not be found. See the error message for details. **409** There was a request conflict with the current state of the target resource. See the error message for details. **500** The server encountered an internal error. See the error message for details. put/v3/application/shops/{shop\_id}/policies/return/{return\_policy\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/shops/{shop\_id}/policies/return/{return\_policy\_id} ### Response samples * 200 * 400 * 401 * 403 * 404 * 409 * 500 Content type application/json Copy Expand all Collapse all `{ * "return_policy_id": 1, * "shop_id": 1, * "accepts_returns": true, * "accepts_exchanges": true, * "return_deadline": 0 }` [](https://developers.etsy.com/documentation/reference#tag/User) User ===================================================================== [](https://developers.etsy.com/documentation/reference#operation/getUser) getUser --------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Retrieves a user profile based on a unique user ID. Access is limited to profiles of the authenticated user or linked buyers. For the primary\_email field, specific app-based permissions are required and granted case-by-case. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`email_r`) ##### path Parameters | | | | --- | --- | | user\_id

required | integer \>= 1 | ### Responses **200** A single User **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/users/{user\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/users/{user\_id} ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "user_id": 1, * "primary_email": "user@example.com", * "first_name": "string", * "last_name": "string", * "image_url_75x75": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getMe) getMe ----------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Returns basic info for the user making the request. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`shops_r`) ### Responses **200** Fetches basic info about the requesting user **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/users/me Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/users/me ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "user_id": 1, * "shop_id": 1 }` [](https://developers.etsy.com/documentation/reference#tag/UserAddress) UserAddress =================================================================================== [](https://developers.etsy.com/documentation/reference#operation/deleteUserAddress) deleteUserAddress ----------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 endpoint to delete a UserAddress for a User. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`address_r`) ##### path Parameters | | | | --- | --- | | user\_address\_id

required | integer \>= 1

The numeric ID of the user's address. | ### Responses **204** The User Address resource was correctly deleted **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **500** The server encountered an internal error. See the error message for details. delete/v3/application/user/addresses/{user\_address\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/user/addresses/{user\_address\_id} ### Response samples * 400 * 401 * 500 Content type application/json Copy Expand all Collapse all `{ * "error": "string" }` [](https://developers.etsy.com/documentation/reference#operation/getUserAddress) getUserAddress ----------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 endpoint to retrieve a UserAddress for a User. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`address_r`) ##### path Parameters | | | | --- | --- | | user\_address\_id

required | integer \>= 1

The numeric ID of the user's address. | ### Responses **200** A single UserAddress **400** There was a problem with the request data. See the error message for details. **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/user/addresses/{user\_address\_id} Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/user/addresses/{user\_address\_id} ### Response samples * 200 * 400 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "user_address_id": 1, * "user_id": 1, * "name": "string", * "first_line": "string", * "second_line": "string", * "city": "string", * "state": "string", * "zip": "string", * "iso_country_code": "string", * "country_name": "string", * "is_default_shipping_address": true }` [](https://developers.etsy.com/documentation/reference#operation/getUserAddresses) getUserAddresses --------------------------------------------------------------------------------------------------- General Release[Report bug](https://github.com/etsy/open-api/discussions) This endpoint is ready for production use. Open API V3 endpoint to retrieve UserAddresses for a User. ##### Authorizations: [api\_key](https://developers.etsy.com/documentation/reference#section/Authentication/api_key) [oauth2](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) (`address_r`) ##### query Parameters | | | | --- | --- | | limit | integer \[ 1 .. 100 \]

Default: 25

The maximum number of results to return. | | offset | integer \>= 0

Default: 0

The number of records to skip before selecting the first result. | ### Responses **200** A list of UserAddress records **401** The request lacks valid authentication credentials. See the error message for details. **404** A resource could not be found. See the error message for details. **500** The server encountered an internal error. See the error message for details. get/v3/application/user/addresses Base URL for all Open API endpoints. https://openapi.etsy.com/v3/application/user/addresses ### Response samples * 200 * 401 * 404 * 500 Content type application/json Copy Expand all Collapse all `{ * "count": 0, * "results": [ * { * "user_address_id": 1, * "user_id": 1, * "name": "string", * "first_line": "string", * "second_line": "string", * "city": "string", * "state": "string", * "zip": "string", * "iso_country_code": "string", * "country_name": "string", * "is_default_shipping_address": true } ] }` --- # Shop Management Tutorial | Etsy Open API v3 ##### important These tutorials are subject to change as endpoints change during our feedback period development. We welcome your feedback! If you find an error or have a suggestion, please post it in the [Open API GitHub Repository](https://github.com/etsy/open-api) . An Etsy shop is a common resource to organize a seller's listings and service buyers, and every Etsy user has at least one shop. Shops contain references to all resource, listing, and sales records, including previously uploaded files, images, shipping profiles, and deleted listings. Apps create or update most of these references using resource-specific endpoints, but require a shop ID to access them. You can update the shop and create shop sections using requests to the shop resource directly. The Etsy Open API v3 supports managing individual shops or shops across the Etsy marketplace as a whole, depending on your application's [Access Level](https://developers.etsy.com/documentation/tutorials/#personal-access) . _Throughout this tutorial, the instructions reference REST resources, endpoints, parameters, and response fields, which we cover in detail in [Request Standards](https://developers.etsy.com/documentation/tutorials/essentials/requests) and [URL Syntax](https://developers.etsy.com/documentation/tutorials/essentials/urlsyntax) ._ ### `Authorization` and `x-api-key` header parameters[#](https://developers.etsy.com/documentation/tutorials/shopmanagement#authorization-and-x-api-key-header-parameters "Direct link to heading") The endpoints in this tutorial require an OAuth token in the header with `shops_r` and `shops_w` scope. In addition, to assign Listings to a shop section ([see below](https://developers.etsy.com/documentation/tutorials/shopmanagement#add-a-shop-section) ), you require an OAuth token with a `listings_w` scope. See the [Authentication topic](https://developers.etsy.com/documentation/tutorials/essentials/authentication) for instructions on how to generate an OAuth token with these scopes. In addition, all Open API V3 requests require the `x-api-key:` parameter in the header with your shop's Etsy App API Key _keystring_ and _shared secret_, separated by a colon (`:`), which you can find in [Your Apps](https://www.etsy.com/developers/your-apps) . Customize announcements and sales messages[#](https://developers.etsy.com/documentation/tutorials/shopmanagement#customize-announcements-and-sales-messages "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- You can assign and change the following attributes for a shop using the [`updateShop`](https://developers.etsy.com/documentation/reference/#operation/updateShop) endpoint: * `title`: The title displayed at the top of all the shop's pages * `announcement`: A message displayed on the shop's homepage * `sale_message`: A message sent to the buyer's Etsy messages when they purchase any product from this shop * `digital_sale_message`: A message sent to the buyer's Etsy messages when they purchase any digital product from this shop The following procedure changes the messages for a shop: 1. Form a valid URL for [`updateShop`](https://developers.etsy.com/documentation/reference/#operation/updateShop) , which must include your `shop_id`. For example, if your shop\_id is 12345678, the updateShop URL is: https://api.etsy.com/v3/application/shops/12345678 Copy 2. Build the updateShop request body with the messages you want to update. All the parameters accept string values. 3. Execute an updateShop PUT request with a `shops_r` and `shops_w` combined scope OAuth token and `x-api-key`. For example, an updateShop request to update all messages for Manny's Land of Carpets would look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "2lk6cu87j83a15eqnfmf7ysk:a1b2c3d4e5:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var urlencoded \= new URLSearchParams(); urlencoded.append("title", "Manny's Land of Carpets"); urlencoded.append("announcement", "Welcome to the amazing world of carpets!"); urlencoded.append("sale\_message", "Manny's Land of Carpets would like to personally congratulate you on your carpet purchase! We are assembling your order and will ship it to you immediately upon receiving payment. You should receive an email in the next 24 hours with a receipt for your purchase and shipping options for your region."); urlencoded.append("digital\_sale\_message", "All digital carpet sales are final."); var requestOptions \= { method: 'PUT', headers: headers, body: urlencoded, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'PUT', CURLOPT\_POSTFIELDS \=> 'title=Manny%27s%20Land%20of%20Carpets%21&announcement=Welcome%20to%20the%20amazing%20world%20of%20carpets%21&sale\_message=Manny%27s%20Land%20of%20Carpets%20would%20like%20to%20personally%20congratulate%20you%20on%20your%20carpet%20purchase%21%20We%20are%20assembling%20your%20order%20and%20will%20ship%20it%20to%20you%20immidiately%20upon%20recieving%20payment.%20You%20should%20recieve%20an%20email%20in%20the%20next%2024%20hours%20with%20a%20receipt%20for%20your%20purchase%20and%20shipping%20options%20for%20your%20region.&digital\_sale\_message=All%20digital%20carpet%20sales%20are%20final.' CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 2lk6cu87j83a15eqnfmf7ysk:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy Add a Shop Section[#](https://developers.etsy.com/documentation/tutorials/shopmanagement#add-a-shop-section "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------- Shop sections organize listings displayed in an Etsy shop. You can create shop sections using the [`createShopSection`](https://developers.etsy.com/documentation/reference/#operation/createShopSection) endpoint, which provides the new shop section ID in the response. To add a listing to a shop section, use the `updateListing` endpoint with the `section_id` parameter set to a section ID. The following procedure creates a new shop section and updates a listing to display in the new shop section: 1. Form a valid URL for [`createShopSection`](https://developers.etsy.com/documentation/reference/#operation/createShopSection) , which must include your `shop_id`. For example, if your shop\_id is 12345678, the createShopSection URL is: https://api.etsy.com/v3/application/shops/12345678/sections Copy 2. Build the createShopSection request body, which must include `title` with a string to display at the top of a section in the shop. 3. Execute a createShopSection POST request with a `shops_w` scope OAuth token and `x-api-key`. For example, a createShopSection request to create the "Spiral Carpet" section might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "2lk6cu87j83a15eqnfmf7ysk:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var urlencoded \= new URLSearchParams(); urlencoded.append("title", "Spiral Carpet"); var requestOptions \= { method: 'POST', headers: headers, body: urlencoded, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/sections", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678/sections', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'POST', CURLOPT\_POSTFIELDS \=> 'title=Spiral%20Carpet' CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 2lk6cu87j83a15eqnfmf7ysk:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy 4. Set all listings' section\_ids to the section ID for the section in which you want to display the listings with an [`updateListing`](https://developers.etsy.com/documentation/reference/#operation/updateListing) PUT request that includes `shop_id` and `listing_id` in the URL, a `listings_w` scoped OAuth token and `x-api-key` in the header, and the new section ID in the request body. For example, if your `shop_id` is 12345678, your `listing_id` is 192837465, and your `section_id` is 55566585, then the updateListing URL is: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "2lk6cu87j83a15eqnfmf7ysk:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var urlencoded \= new URLSearchParams(); urlencoded.append("section\_id", "55566585"); var requestOptions \= { method: 'PUT', headers: headers, body: urlencoded, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/listings/192837465", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678/listings/192837465', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'PUT', CURLOPT\_POSTFIELDS \=> 'section\_id=55566585' CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 2lk6cu87j83a15eqnfmf7ysk:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy * [`Authorization` and `x-api-key` header parameters](https://developers.etsy.com/documentation/tutorials/shopmanagement#authorization-and-x-api-key-header-parameters) * [Customize announcements and sales messages](https://developers.etsy.com/documentation/tutorials/shopmanagement#customize-announcements-and-sales-messages) * [Add a Shop Section](https://developers.etsy.com/documentation/tutorials/shopmanagement#add-a-shop-section) --- # Listings Tutorial | Etsy Open API v3 ##### important These tutorials are subject to change as endpoints change during our feedback period development. We welcome your feedback! If you find an error or have a suggestion, please post it in the [Open API GitHub Repository](https://github.com/etsy/open-api) . Listings are the pages containing products for sale in an Etsy shop. The Etsy Open API v3 supports managing listings either for an individual shop or across the Etsy marketplace as a whole, depending on your application's [Access Level](https://developers.etsy.com/documentation/#personal-access) . _Throughout this tutorial, the instructions reference REST resources, endpoints, parameters, and response fields, which we cover in detail in [Request Standards](https://developers.etsy.com/documentation/essentials/requests) and [URL Syntax](https://developers.etsy.com/documentation/essentials/urlsyntax) ._ ### `Authorization` and `x-api-key` header parameters[#](https://developers.etsy.com/documentation/tutorials/listings#authorization-and-x-api-key-header-parameters "Direct link to heading") The endpoints in this tutorial require an OAuth token in the header with `listings_r` and `listings_w` scope. If your app also deletes listings, then the token requires the `listings_d` scope as well. See the [Authentication topic](https://developers.etsy.com/documentation/essentials/oauth2) for instructions on how to generate an OAuth token with these scopes. In addition, all Open API V3 Requests require the `x-api-key:` parameter in the header with your shop's Etsy App API Key _keystring_ and _shared secret_, separated by a colon (`:`), which you can find in [Your Apps](https://www.etsy.com/developers/your-apps) . ### Listing lifecycle and state[#](https://developers.etsy.com/documentation/tutorials/listings#listing-lifecycle-and-state "Direct link to heading") After creating a listing, your users, Etsy, or your application can change the listing to reflect several states that determine how customers interact with the listing and the effective changes available to sellers, which map to API endpoints. The following table summarizes the states and the change operations available from the API. | state | description | Actions and endpoints | | --- | --- | --- | | draft | inactive listing because its `state` is not "active" or lacks at least one image | Publish (`updateListing`), Delete (`deleteListing`) | | published | active listing searchable by users, with > 0 unsold inventory | Deactivate (`updateListing`), Delete (`deleteListing`) | | deactivated | previously published listing deliberately deactivated, unsearchable, and unsellable | Publish (`updateListing`), Delete (`deleteListing`) | | sold out | published listing with 0 unsold inventory | Delete (`deleteListing`) | | expired | previously published listing older that was not renewed after expiring (not charged) | Publish (`updateListing`), Delete (`deleteListing`) | Listing a physical product for sale[#](https://developers.etsy.com/documentation/tutorials/listings#listing-a-physical-product-for-sale "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------ To add a new listing to a shop, use the [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) endpoint, which adds a single item for sale to an Etsy Shop. All published listings require at least one listing image, so your application must either: * use images already uploaded to the shop, or * upload listing images - see [Adding an image to a listing](https://developers.etsy.com/documentation/tutorials/listings#adding-an-image-to-a-listing) The following procedure adds a listing using images already uploaded to the shop: 1. Form a valid URL for [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) , which must include a `shop_id` for the shop that hosts the listing. For example, if your shop\_id is : "12345678", the [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) URL is: https://api.etsy.com/v3/application/shops/12345678/listings Copy 2. Build the [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) request body, which must include at a minimum: * `quantity` * `title` * `description` * `price` * `who_made` * `when_made` * `taxonomy_id` * `image_ids` required for active listings * `shipping_profile_id` required for physical listings * `readiness_state_id` required for physical listings 3. Execute a [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) POST request with your `listings_w` scoped OAuth token and `x-api-key`. For example, a [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) request to list 5 yo-yos might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var urlencoded \= new URLSearchParams(); urlencoded.append("quantity", "5"); urlencoded.append("title", "Vintage Duncan Toys Butterfly Yo-Yo, Red"); urlencoded.append("description", "Vintage Duncan Yo-Yo from 1976 with string, steel axle, and plastic body."); urlencoded.append("price", "1000"); urlencoded.append("who\_made", "someone\_else"); urlencoded.append("when\_made", "1970s"); urlencoded.append("taxonomy\_id", "1"); urlencoded.append("image\_ids", "378848,238298,030076"); urlencoded.append("shipping\_profile\_id", "6722757781"); urlencoded.append("readiness\_state\_id", "18201076875"); var requestOptions \= { method: 'POST', headers: headers, body: urlencoded, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/listings", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678/listings', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'POST', CURLOPT\_POSTFIELDS \=> 'quantity=5&title=Vintage%20Duncan%20Toys%20Butterfly%20Yo-Yo%2C%20Red&description=Vintage%20Duncan%20Yo-Yo%20from%201976%20with%20string%2C%20steel%20axle%2C%20and%20plastic%20body.&price=1000&who\_made=someone\_else&when\_made=1970s&taxonomy\_id=1&image\_ids=378848%2C238298%2C030076&shipping\_profile\_id=6722757781&readiness\_state\_id=18201076875' CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy To sell variations of the same product in the same listing, such as different colored products with specific quantities for sale in each color, see [Listing inventory with different properties, quantities, and prices](https://developers.etsy.com/documentation/tutorials/listings#listing-inventory-with-different-properties-quantities-and-prices) below. Listing a digital product for sale[#](https://developers.etsy.com/documentation/tutorials/listings#listing-a-digital-product-for-sale "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------------------------------------------- To list a digital product for sale, use [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) just as you would for a physical product, but your application must set the listing's `type` parameter to "download" and upload a digital product file for the digital product listing using [`uploadListingFile`](https://developers.etsy.com/documentation/reference/#operation/uploadListingFile) . If you already uploaded a digital product file to your shop, for example as part of previous listing, you can associate the file with a listing using [`uploadListingFile`](https://developers.etsy.com/documentation/reference/#operation/uploadListingFile) with its file ID as well. Each file in a shop is unique and managed separately, so you cannot assign or upload a file with [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing) . The following procedure uploads a digital product file to a listing and updates the listing's `type` parameter to "download": 1. Form a valid URL for [`uploadListingFile`](https://developers.etsy.com/documentation/reference/#operation/uploadListingFile) , which must include a `shop_id` and `listing_id` to assign the digital product file to a listing. For example, if your `shop_id` is "12345678" and your `listing_id` is "192837465," then the uploadListingFile URL is: https://api.etsy.com/v3/application/shops/12345678/listings/192837465/files Copy 2. Build the [`uploadListingFile`](https://developers.etsy.com/documentation/reference/#operation/uploadListingFile) request body, which must include either a `file` (binary) parameter for a digital product file to upload or a `file_id` for a file already uploaded to the shop, but not both. 3. Execute an [`uploadListingFile`](https://developers.etsy.com/documentation/reference/#operation/uploadListingFile) POST request with your `listings_w` scoped OAuth token and `x-api-key`. For example, an [`uploadListingFile`](https://developers.etsy.com/documentation/reference/#operation/uploadListingFile) request might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var urlencoded \= new URLSearchParams(); urlencoded.append("file", "v8%&^%&$38owf87leshif;hnvygsldjkhnvusidsba',;bf.r;'e,rl;rtkjrj87^\*^&\_Iuyibdsa\*^5765FtIG YtfDbf86af\*rfdiidtbsdiGIgdi7vleikvvvkdljke ... d\[L>(\*BKbaukyfgdg'jsdkbklvh");\ \ var requestOptions \= {\ \ method: 'POST',\ \ headers: headers,\ \ body: urlencoded,\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/shops/12345678/listings/192837465/files", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/shops/12345678/listings/192837465/files',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'POST',\ \ CURLOPT\_POSTFIELDS \=> 'file=v8%&^%&$38owf87leshif;hnvygsldjkhnvusidsba',;bf.r;'e,rl;rtkjrj87^\*^&\_Iuyibdsa\*^5765FtIG YtfDbf86af\*rfdiidtbsdiGIgdi7vleikvvvkdljke ... d\[L>(\*BKbaukyfgdg'jsdkbklvh'\ \ CURLOPT\_HTTPHEADER => array(\ \ 'Content\-Type: application/x\-www\-form\-urlencoded',\ \ 'x\-api\-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ 4. Set the listing's `type` to "download" with an [`updateListing`](https://developers.etsy.com/documentation/reference/#operation/updateListing)\ PATCH request that includes `shop_id` and `listing_id` in the URL, a `listings_w` scoped OAuth token and `x-api-key` in the header, and the `type` setting in the request body. For example, an [`updateListing`](https://developers.etsy.com/documentation/reference/#operation/updateListing)\ request might look like the following:\ \ * JavaScript fetch\ * PHP curl\ \ var headers \= new Headers();\ \ headers.append("Content-Type", "application/x-www-form-urlencoded");\ \ headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5");\ \ headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz");\ \ var urlencoded \= new URLSearchParams();\ \ urlencoded.append("type", "download");\ \ var requestOptions \= {\ \ method: 'PATCH',\ \ headers: headers,\ \ body: urlencoded,\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/shops/12345678/listings/192837465", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/shops/12345678/listings/192837465',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'PATCH',\ \ CURLOPT\_POSTFIELDS \=> 'type=download'\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: application/x-www-form-urlencoded',\ \ 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ Converting a physical product listing to a digital product listing[#](https://developers.etsy.com/documentation/tutorials/listings#converting-a-physical-product-listing-to-a-digital-product-listing "Direct link to heading")\ \ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\ \ In the event that a physical product listing needs to be changed to a digital listing, this can be accomplished via the [`updateListing`](https://developers.etsy.com/documentation/reference/#operation/updateListing)\ endpoint and passing `type` as "download". However, note that if the physical product listing has any variations or inventory beyond a single product, [`updateListing`](https://developer.etsy.com/documentation/reference/#operation/updateListing)\ will return a 409 error. Before converting any physical listing to digital, the inventory must be reset to a single product using the [`uploadListingInventory`](https://developers.etsy.com/documentation/reference/#operation/uploadListingInventory)\ endpoint.\ \ The following is an example body of the [`uploadListingInventory`](https://developers.etsy.com/documentation/reference/#operation/uploadListingInventory)\ post (set your price as a float value and your sku):\ \ {\ \ "products": \[\ \ {\ \ "sku": "YOUR SKU HERE",\ \ "offerings": \[\ \ {\ \ "quantity": 1,\ \ "is\_enabled": true,\ \ "price": 1.23,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\]\ \ }\ \ \],\ \ "price\_on\_property": \[\],\ \ "quantity\_on\_property": \[\],\ \ "sku\_on\_property": \[\]\ \ }\ \ Copy\ \ Adding an image to a listing[#](https://developers.etsy.com/documentation/tutorials/listings#adding-an-image-to-a-listing "Direct link to heading")\ \ ----------------------------------------------------------------------------------------------------------------------------------------------------\ \ Published listings require at least one listing image, as noted above. To upload a new image and add it to a listing, use the [`uploadListingImage`](https://developers.etsy.com/documentation/reference/#operation/uploadListingImage)\ endpoint with the shop and listing IDs, and add the image binary file in the `image` parameter. To make a listing active after uploading a required image, use the [`updateListing`](https://developer.etsy.com/documentation/reference/#operation/updateListing)\ endpoint with the `state` parameter set to "active." As noted above, you can associate images with listings in a `createDraftListing` request using the `image_ids` parameter if images are already uploaded to your shop.\ \ The following procedure uploads an image to a listing and updates the listing to active:\ \ 1. Form a valid URL for [`uploadListingImage`](https://developers.etsy.com/documentation/reference/#operation/uploadListingImage)\ , which must include a `shop_id` and `listing_id` to assign the image to a listing. For example, if your `shop_id` is "12345678" and your `listing_id` is "192837465," then the [`uploadListingImage`](https://developers.etsy.com/documentation/reference/#operation/uploadListingImage)\ URL is:\ \ https://api.etsy.com/v3/application/shops/12345678/listings/192837465/images\ \ Copy\ \ 2. Build the [`uploadListingImage`](https://developers.etsy.com/documentation/reference/#operation/uploadListingImage)\ request body, which must include either an `image` (binary) parameter with a digital image as its value or a `listing_image_id` for an image uploaded to the shop, but not both.\ \ 3. Execute an [`uploadListingImage`](https://developers.etsy.com/documentation/reference/#operation/uploadListingImage)\ POST request with your `listings_w` scoped OAuth token and `x-api-key`. For example, an [`uploadListingImage`](https://developers.etsy.com/documentation/reference/#operation/uploadListingImage)\ request might look like the following:\ \ \ * JavaScript fetch\ * Node JS\ * PHP curl\ \ var myHeaders \= new Headers();\ \ myHeaders.append("Content-Type", "multipart/form-data");\ \ myHeaders.append("x-api-key", "112233445566778899:a1b2c3d4e5");\ \ myHeaders.append("Authorization", "Bearer abcd1234efgh5678ijkl90mnopqrst");\ \ var formdata \= new FormData();\ \ formdata.append("image", fileInput.files\[0\], "image.jpg");\ \ var requestOptions \= {\ \ method: 'POST',\ \ headers: myHeaders,\ \ body: formdata,\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/shops/xxxxxxxx/listings/yyyyyyyy/images", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ var request \= require('request');\ \ var fs \= require('fs');\ \ var options \= {\ \ 'method': 'POST',\ \ 'url': 'https://api.etsy.com/v3/application/shops/xxxxxxxx/listings/yyyyyyyy/images',\ \ 'headers': {\ \ 'Content-Type': 'multipart/form-data',\ \ 'x-api-key': '112233445566778899:a1b2c3d4e5',\ \ 'Authorization': 'Bearer abcd1234efgh5678ijkl90mnopqrst'\ \ },\ \ formData: {\ \ 'image': {\ \ 'value': fs.createReadStream('/path/to/my/image.jpg'),\ \ 'options': {\ \ 'filename': 'image.jpg',\ \ 'contentType': null\ \ }\ \ }\ \ }\ \ };\ \ request(options, function (error, response) {\ \ if (error) throw new Error(error);\ \ console.log(response.body);\ \ });\ \ Copy\ \ 'https://api.etsy.com/v3/application/shops/xxxxxxxx/listings/yyyyyyyy/images',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'POST',\ \ CURLOPT\_POSTFIELDS \=> array('image'\=> new CURLFILE('/path/to/my/image.jpg')),\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: multipart/form-data',\ \ 'x-api-key: 112233445566778899:a1b2c3d4e5',\ \ 'Authorization: Bearer abcd1234efgh5678ijkl90mnopqrst'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ 4. Set the Listing's `state` to "active" with an [`updateListing`](https://developers.etsy.com/documentation/reference/#operation/updateListing)\ PATCH request that includes `shop_id` and `listing_id` in the URL, a `listings_w` scoped OAuth token and `x-api-key` in the header, and the new `state` in the request body. For example, an updateListing request might look like the following:\ \ * JavaScript fetch\ * PHP curl\ \ var headers \= new Headers();\ \ headers.append("Content-Type", "application/x-www-form-urlencoded");\ \ headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5");\ \ headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz");\ \ var urlencoded \= new URLSearchParams();\ \ urlencoded.append("state", "active");\ \ var requestOptions \= {\ \ method: 'PATCH',\ \ headers: headers,\ \ body: urlencoded,\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/shops/12345678/listings/192837465", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/shops/12345678/listings/192837465',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'PATCH',\ \ CURLOPT\_POSTFIELDS \=> 'state=active'\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: application/x-www-form-urlencoded',\ \ 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ Listing inventory with different properties, quantities, and prices[#](https://developers.etsy.com/documentation/tutorials/listings#listing-inventory-with-different-properties-quantities-and-prices "Direct link to heading")\ \ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\ \ Inventory is a list of products for sale in a listing. The products are customizable, so understanding the inventory request structure is vital to offering different variations of the same product in one listing. Inventory defines products using the following components:\ \ * `sku`: Stock Keeping Unit (SKU) assigned to this product.\ * `offerings`: a list of prices and quantities associated with a specific product, representing purchase options visible to buyers on the Etsy shop.\ * `quantity`: the number of products available at this offering price\ * `price`: a number indicating the price of this product interpreted in the default currency of the listing/shop, which is US pennies by default.\ * `is_enabled`: when true, the offering is visible to buyers in the listing.\ * `readiness_state_id`: the processing profile associated with the offering, if processing profile is set at listing level this id will be the same across all offerings.\ * `property_values`: A list of properties differentiating this product from other products in a listing. For example, to sell sets of bed sheets in different color (white, blue, magenta, forest green, etc) and size (twin, full, queen, king) combinations, use property\_values for color and size.\ * `property_id`: a unique number identifying this property.\ * `property_name`: a string name for a property.\ * `scale_id`: a number indexing an Etsy-defined scale. There are a lot of these, but for example shoe sizes have three available scales:\ \ | Scale ID | Scale Name | Value IDs and Names |\ | --- | --- | --- |\ | 17 | US/Canada | value\_id:1329,"name":"0 (Baby)", value\_id:1330,"name":"0.5 (Baby)", value\_id:1331,"name":"1 (Baby)", value\_id:1332,"name":"1.5 (Baby)", value\_id:1333,"name":"2 (Baby)", value\_id:1334,"name":"2.5 (Baby)", value\_id:1335,"name":"3 (Baby)", value\_id:1336,"name":"3.5 (Baby)", value\_id:1337,"name":"4 (Baby)", value\_id:1338,"name":"4.5 (Walker)", value\_id:1339,"name":"5 (Walker)", value\_id:1340,"name":"5.5 (Walker)", value\_id:1341,"name":"6 (Walker)", value\_id:1342,"name":"6.5 (Walker)", value\_id:1343,"name":"7 (Walker)", value\_id:1344,"name":"7.5 (Toddler)", value\_id:1345,"name":"8 (Toddler)", value\_id:1346,"name":"8.5 (Toddler)", value\_id:1347,"name":"9 (Toddler)", value\_id:1348,"name":"9.5 (Toddler)", value\_id:1349,"name":"10 (Toddler)", value\_id:1350,"name":"10.5 (Toddler)", value\_id:1351,"name":"11 (Toddler)", value\_id:1352,"name":"11.5 (Toddler)", value\_id:1353,"name":"12 (Toddler)", value\_id:1354,"name":"12.5 (Youth)", value\_id:1355,"name":"13 (Youth)", value\_id:1356,"name":"13.5 (Youth)", value\_id:1357,"name":"1 (Youth)", value\_id:1358,"name":"1.5 (Youth)", value\_id:1359,"name":"2 (Youth)", value\_id:1360,"name":"2.5 (Youth)", value\_id:1361,"name":"3 (Youth)", value\_id:1362,"name":"3.5 (Youth)", value\_id:1363,"name":"4 (Youth)", value\_id:1364,"name":"4.5 (Youth)", value\_id:1365,"name":"5 (Youth)", value\_id:1366,"name":"5.5 (Youth)", value\_id:1367,"name":"6 (Youth)", value\_id:1368,"name":"6.5 (Youth)", value\_id:1369,"name":"7 (Youth)" |\ | 18 | EU | "value\_id":1370,"name":"15", "value\_id":1371,"name":"16", "value\_id":1372,"name":"17", "value\_id":1373,"name":"18", "value\_id":1374,"name":"19", "value\_id":1375,"name":"20", "value\_id":1376,"name":"21", "value\_id":1377,"name":"22", "value\_id":1378,"name":"23", "value\_id":1379,"name":"24", "value\_id":1380,"name":"25", "value\_id":1381,"name":"26", "value\_id":1382,"name":"27", "value\_id":1383,"name":"28", "value\_id":1385,"name":"29", "value\_id":1386,"name":"30", "value\_id":1387,"name":"31", "value\_id":1388,"name":"32", "value\_id":1389,"name":"33", "value\_id":1390,"name":"34", "value\_id":1391,"name":"35", "value\_id":1392,"name":"36", "value\_id":1393,"name":"37", "value\_id":1394,"name":"38", "value\_id":1395,"name":"39" |\ | 19 | UK | value\_id:1396,"name":"0 (Baby)", value\_id:1397,"name":"0.5 (Baby)", value\_id:1399,"name":"1 (Baby)", value\_id:1401,"name":"1.5 (Baby)", value\_id:1402,"name":"2 (Baby)", value\_id:1403,"name":"2.5 (Baby)", value\_id:1404,"name":"3 (Baby)", value\_id:1405,"name":"3.5 (Walker)", value\_id:1406,"name":"4 (Walker)", value\_id:1407,"name":"4.5 (Walker)", value\_id:1408,"name":"5 (Walker)", value\_id:1409,"name":"5.5 (Walker)", value\_id:1410,"name":"6 (Walker)", value\_id:1411,"name":"6.5 (Toddler)", value\_id:1412,"name":"7 (Toddler)", value\_id:1413,"name":"7.5 (Toddler)", value\_id:1414,"name":"8 (Toddler)", value\_id:1415,"name":"8.5 (Toddler)", value\_id:1416,"name":"9 (Toddler)", value\_id:1417,"name":"9.5 (Toddler)", value\_id:1418,"name":"10 (Toddler)", value\_id:1419,"name":"10.5 (Toddler)", value\_id:1420,"name":"11 (Toddler)", value\_id:1421,"name":"11.5 (Youth)", value\_id:1422,"name":"12 (Youth)", value\_id:1423,"name":"12.5 (Youth)", value\_id:1424,"name":"13 (Youth)", value\_id:1425,"name":"13.5 (Youth)", value\_id:1426,"name":"1 (Youth)", value\_id:1428,"name":"2 (Youth)", value\_id:1429,"name":"2.5 (Youth)", value\_id:1430,"name":"3 (Youth)", value\_id:1431,"name":"3.5 (Youth)", value\_id:1432,"name":"4 (Youth)", value\_id:1433,"name":"4.5 (Youth)", value\_id:1434,"name":"5 (Youth)", value\_id:1435,"name":"5.5 (Youth)", value\_id:1436,"name":"6 (Youth)" |\ \ * `value_ids`: a list of numbers valid for the `scale_id` selected indicating the product variations.\ * `values`: a list of strings matching the value ids selected.\ \ The following endpoints change the listing properties and inventory for an existing listing:\ \ 1. [`updateListingProperty`](https://developers.etsy.com/documentation/reference/#operation/updateListingProperty)\ adds properties to a listing\ 2. [`updateListingInventory`](https://developers.etsy.com/documentation/reference/#operation/updateListingInventory)\ assigns skus to offerings for different property combinations\ \ ### Updating Inventory[#](https://developers.etsy.com/documentation/tutorials/listings#updating-inventory "Direct link to heading")\ \ The following procedure adds a product for sale in a listing:\ \ 1. Form a valid URL for [`updateListingInventory`](https://developers.etsy.com/documentation/reference/#operation/updateListingInventory)\ , which must include a `listing_id` to change the inventory in a listing. For example, if your `listing_id` is "192837465," then the updateListingInventory URL is:\ \ https://api.etsy.com/v3/application/listings/192837465/inventory\ \ Copy\ \ 2. Build the [`updateListingInventory`](https://developers.etsy.com/documentation/reference/#operation/updateListingInventory)\ request body, which must include at least one product in the `products` parameter with nested `offerings` and `property_values` lists.\ \ 3. Execute an [`updateListingInventory`](https://developers.etsy.com/documentation/reference/#operation/updateListingInventory)\ PUT request with a `listings_w` scoped OAuth token and `x-api-key`. For example, an [`updateListingInventory`](https://developers.etsy.com/documentation/reference/#operation/updateListingInventory)\ request to add 10 US/Canada size 4 shoes with a sku of 7836646 might look like the following:\ \ \ * JavaScript fetch\ * PHP curl\ \ var headers \= new Headers();\ \ headers.append("Content-Type", "application/json");\ \ headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5");\ \ headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz");\ \ var productsArray \= {\ \ "products": \[\ \ {\ \ "sku": "7836646",\ \ "property\_values": \[\ \ {\ \ "property\_id": 1,\ \ "property\_name": "size 4",\ \ "scale\_id": 17,\ \ "value\_ids": \[\ \ 1363\ \ \],\ \ "values": \[\ \ "4 (Youth)"\ \ \],\ \ }\ \ \],\ \ "offerings": \[\ \ {\ \ "price": 500,\ \ "quantity": 10,\ \ "is\_enabled": true,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \]\ \ }\ \ \]\ \ };\ \ var requestOptions \= {\ \ method: 'PUT',\ \ headers: headers,\ \ body: JSON.stringify(productsArray),\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/listings/192837465/inventory", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/listings/192837465/inventory',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'PUT',\ \ CURLOPT\_POSTFIELDS \=>'{\ \ "products": \[\ \ {\ \ "sku": "7836646",\ \ "property\_values": \[\ \ {\ \ "property\_id": 1,\ \ "property\_name": "Size",\ \ "scale\_id": 17,\ \ "value\_ids": \[\ \ 1363\ \ \],\ \ "values": \[\ \ "4 (Youth)"\ \ \],\ \ }\ \ \],\ \ "offerings": \[\ \ {\ \ "price": 500,\ \ "quantity": 10,\ \ "is\_enabled": true,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \]\ \ }\ \ \],\ \ "price\_on\_property": \[1\],\ \ "quantity\_on\_property": \[\],\ \ "sku\_on\_property": \[\]\ \ }',\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: application/json',\ \ 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ **NOTES:**\ \ 1. When updating inventory, the entire set of products (based on variations) must be in the `products` array.\ \ 2. To get the product array, call [`getListingInventory`](https://developer.etsy.com/documentation/reference/#operation/getListingInventory)\ for the listing. From the [`getListingInventory`](https://developer.etsy.com/documentation/reference/#operation/getListingInventory)\ response, remove the following fields: `product_id`, `offering_id`, `scale_name`, `is_deleted` and `value_pairs`. Also change the `price` array in offerings to be a decimal value instead of an array.\ \ 3. The `*_on_property` values should match the `property_id` values, but only if those properties affect the price, quantity or sku. See the sample below for handling variations.\ \ 4. Use [Custom Variations](https://developers.etsy.com/documentation/tutorials/listings#custom-variations)\ if any of the existing attributes don't exist or fit your use case.\ \ \ ### Handling Variations in Inventory Updates[#](https://developers.etsy.com/documentation/tutorials/listings#handling-variations-in-inventory-updates "Direct link to heading")\ \ The following example updates a listing inventory where there are two variations:\ \ 1. Material - "Pine", "Oak", "Walnut"\ \ 2. Size - "3", "4", "5"\ \ \ In this example, the material variation affects the price, while the size variation affects the quantity and sku of the product.\ \ In the `products` array, you will have 9 entries (3 materials x 3 sizes).\ \ Due to the size affecting both quantity and sku, when quantity is updated it must be the same value across all products sharing the same sku. The sku "woodthing3" has 3 entries in the array, but the `quantity` value for all three of those arrays (inside `offerings`) must be the same value (33 in this example).\ \ Similarly, because material affects pricing, in each product you will see that the "Walnut" property value indicates the `price` in `offerings` is 8.00 while "Oak" is 7.00 and "Pine" is 6.00.\ \ Note that since there is only one variation that affects the price, the `price_on_property` value is a single value of `507`, which is the property\_id for "Material". Since size affects both quantity and sku, the `quantity_on_property` and `sku_on_property` values are a single value of `100`, which is the property\_id for "Size".\ \ The processing profile is shared across all offerings, which means that the profile is set at a listing level. See [`Adding a processing profile to a listing`](https://developers.etsy.com/documentation/tutorials/listings#adding-an-processing-profile-to-a-listing)\ for more details about processing profiles.\ \ * JavaScript fetch\ * PHP curl\ \ var headers \= new Headers();\ \ headers.append("Content-Type", "application/json");\ \ headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5");\ \ headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz");\ \ var productsArray \= {\ \ "products": \[\ \ {\ \ "sku": "woodthing3",\ \ "offerings": \[\ \ {\ \ "quantity": 33,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18156809190\ \ \],\ \ "values": \[\ \ "3"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing3",\ \ "offerings": \[\ \ {\ \ "quantity": 33,\ \ "is\_enabled": true,\ \ "price": 7.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18156809190\ \ \],\ \ "values": \[\ \ "3"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18114616675\ \ \],\ \ "values": \[\ \ "Oak"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing3",\ \ "offerings": \[\ \ {\ \ "quantity": 33,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18156809190\ \ \],\ \ "values": \[\ \ "3"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 7.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18114616675\ \ \],\ \ "values": \[\ \ "Oak"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 7.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18114616675\ \ \],\ \ "values": \[\ \ "Oak"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ }\ \ \],\ \ "price\_on\_property": \[507\],\ \ "quantity\_on\_property": \[100\],\ \ "sku\_on\_property": \[100\],\ \ "readiness\_states\_on\_property": \[\]\ \ };\ \ var requestOptions \= {\ \ method: 'PUT',\ \ headers: headers,\ \ body: JSON.stringify(productsArray),\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/listings/192837465/inventory", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/listings/192837465/inventory',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'PUT',\ \ CURLOPT\_POSTFIELDS \=>'{\ \ "products": \[\ \ {\ \ "sku": "woodthing3",\ \ "offerings": \[\ \ {\ \ "quantity": 33,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18156809190\ \ \],\ \ "values": \[\ \ "3"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing3",\ \ "offerings": \[\ \ {\ \ "quantity": 33,\ \ "is\_enabled": true,\ \ "price": 7.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18156809190\ \ \],\ \ "values": \[\ \ "3"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18114616675\ \ \],\ \ "values": \[\ \ "Oak"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing3",\ \ "offerings": \[\ \ {\ \ "quantity": 33,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18156809190\ \ \],\ \ "values": \[\ \ "3"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 7.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18114616675\ \ \],\ \ "values": \[\ \ "Oak"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 7.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18114616675\ \ \],\ \ "values": \[\ \ "Oak"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ }\ \ \],\ \ "price\_on\_property": \[507\],\ \ "quantity\_on\_property": \[100\],\ \ "sku\_on\_property": \[100\],\ \ "readiness\_states\_on\_property": \[\]\ \ }',\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: application/json',\ \ 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ ### Custom Variations[#](https://developers.etsy.com/documentation/tutorials/listings#custom-variations "Direct link to heading")\ \ Custom Variations behave just like normal variations, except you can assign your own custom name to them instead of needing to adhere to attributes. Just like normal variations, there can be at most 2 variations. The `property_ids` for custom variations are `513` and `514`. Use either of these when creating a custom variation.\ \ ### How to Fetch Property Values for the `Products` Array?[#](https://developers.etsy.com/documentation/tutorials/listings#how-to-fetch-property-values-for-the-products-array "Direct link to heading")\ \ Since variations can not be added at the time of creation of a new listing, the following procedure should help with creating the products array for your [`updateListingInventory`](https://developer.etsy.com/documentation/reference/#operation/updateListingInventory)\ call.\ \ The `property_values` is required but may be empty when attempting to post to the endpoint. The properties that may be used for variations on any given listing will depend upon the category the listing is placed in.\ \ Property ids and possible values are available via the following endpoints: [`getSellerTaxonomyNodes`](https://developers.etsy.com/documentation/reference/#operation/getSellerTaxonomyNodes)\ and [`getPropertiesByTaxonomyId`](https://developers.etsy.com/documentation/reference/#operation/getPropertiesByTaxonomyId)\ .\ \ 1. If you don't already have a list of property ids for the product properties you wish to use in the new listing, use a `GET` call to [`getSellerTaxonomyNodes`](https://developers.etsy.com/documentation/reference/#operation/getSellerTaxonomyNodes)\ first to retrieve the full hierarchy tree of seller taxonomy nodes.\ \ 2. In the taxonomy tree, you can look for the category you wish to use and note the id.\ \ 3. Perform a `GET` call to the [`getPropertiesByTaxonomyId`](https://developers.etsy.com/documentation/reference/#operation/getPropertiesByTaxonomyId)\ endpoint with the id of the category. This will give you the possible properties for the category, along with their possible values.\ \ \ **Notes about taxonomy:**\ \ 1. Some of the common taxonomy node properties that Etsy uses, such as `Color` have a list of common values/value ids. When you pass in value\_id `4` we convert that to your shop's unique ID for that color. If it's not already in the system for your shop, it will create one. And then you'll use it over and over again any time you provide 'Green' for the color in the values field OR if you pass in 4 or your custom ID in the value\_ids field and subsequent queries to get inventory should return that custom ID and not our known common ID.\ \ 2. There are also [`getBuyerTaxonomyNodes`](https://developers.etsy.com/documentation/reference/#operation/getBuyerTaxonomyNodes)\ and [`getPropertiesByBuyerTaxonomyId`](https://developers.etsy.com/documentation/reference#operation/getPropertiesByBuyerTaxonomyId)\ endpoints for use by more buyer-facing apps. The difference between the two is that the levels of hierachy in the seller taxonomy is often deeper than that of Buyers. For example, a listing for "blue yarn" is in `All categories` → `Craft Supplies & Tools`. The `Craft Supplies & Tools` is a buyer taxonomy. But in reality, the listing is inside of `All categories` → `Craft Supplies & Tools` → `Yarn & Fiber` → `Yarn`. The `Yarn & Fiber` and `Yarn` category and sub category are the seller taxonomy. For sellers these are very useful categories for sorting and tracking listings. However, from a Buyer perspective, showing the category and subcategory in the category tree would end up cluttering the buyer experience. Since the yarn is really just a craft supply it makes sense to show it under that more top-level category.\ \ \ Adding a shipping profile to a listing[#](https://developers.etsy.com/documentation/tutorials/listings#adding-a-shipping-profile-to-a-listing "Direct link to heading")\ \ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------\ \ Shipping profiles assemble shipping details such as shipping price and processing time for recipients grouped by country or region. Every physical listing requires a shipping profile, so you add shipping profiles to your shop with [`createShopShippingProfile`](https://developers.etsy.com/documentation/reference/#operation/createShopShippingProfile)\ , and assign a shipping profile to a listing using a `shipping_profile_id` when you create or update the listing.\ \ The following procedure creates a new shipping profile and returns the `shipping_profile_id` in the response:\ \ 1. Form a valid URL for [`createShopShippingProfile`](https://developers.etsy.com/documentation/reference/#operation/createShopShippingProfile)\ , which must include a `shop_id`. For example, if your `shop_id` is "12345678", then the [`createShopShippingProfile`](https://developers.etsy.com/documentation/reference/#operation/createShopShippingProfile)\ URL is:\ \ [https://api.etsy.com/v3/application/shops/12345678/shipping-profiles](https://api.etsy.com/v3/application/shops/12345678/shipping-profiles)\ \ 2. Build the [`createShopShippingProfile`](https://developers.etsy.com/documentation/reference/#operation/createShopShippingProfile)\ request body, which must include at a minimum:\ \ \ * `title`: Use a title that indicates the country or region.\ * `origin_country_iso`: The ISO code of the country from which the listing ships.\ * `primary_cost`: The cost of shipping to this country/region alone, measured in the store's default currency.\ * `secondary_cost`: The cost of shipping to this country/region with another item, measured in the store's default currency.\ * `min_processing_time`: The minimum processing time required to process to ship listings with this shipping profile. This field is in deprecation phase and will be removed by Q1 2026.\ * `max_processing_time`: The maximum processing time required to process to ship listings with this shipping profile. This field is in deprecation phase and will be removed by Q1 2026.\ * One of `destination_country_iso` ([see list of Alpha-2 codes here](https://www.iban.com/country-codes)\ ) OR `destination_region` (possible values are "eu" "non\_eu" or "none"), but not both.\ \ 3. Execute an [`createShopShippingProfile`](https://developers.etsy.com/documentation/reference/#operation/createShopShippingProfile)\ POST request with your `shops_w` scoped OAuth token and `x-api-key`, and read the generated `shipping_profile_id` from the response. For example, a [`createShopShippingProfile`](https://developers.etsy.com/documentation/reference/#operation/createShopShippingProfile)\ request for shipments from the US to the EU with free shipping might look like the following:\ \ * JavaScript fetch\ * PHP curl\ \ var headers \= new Headers();\ \ headers.append("Content-Type", "application/x-www-form-urlencoded");\ \ headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5");\ \ headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz");\ \ var urlencoded \= new URLSearchParams();\ \ urlencoded.append("title", "Free shipping to the EU");\ \ urlencoded.append("origin\_country\_iso", "US");\ \ urlencoded.append("primary\_cost", "0");\ \ urlencoded.append("secondary\_cost", "0");\ \ urlencoded.append("min\_processing\_time", "1");\ \ urlencoded.append("max\_processing\_time", "5");\ \ urlencoded.append("destination\_region", "eu");\ \ var requestOptions \= {\ \ method: 'POST',\ \ headers: headers,\ \ body: urlencoded,\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/shops/12345678/shipping-profiles", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/shops/12345678/shipping-profiles',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'POST',\ \ CURLOPT\_POSTFIELDS \=> 'title=Free%20shipping%20to%20the%20EU&"origin\_country\_iso=US&primary\_cost=0&secondary\_cost=0&min\_processing\_time=1&max\_processing\_time=5&destination\_region=eu');\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: application/x-www-form-urlencoded',\ \ 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ 4. Set the listing's `shipping_profile_id` to the shipping profile ID read from the response to setting the shipping profile ID with an [`updateListing`](https://developers.etsy.com/documentation/reference/#operation/updateListing)\ PATCH request that includes `shop_id` and `listing_id` in the URL, a `listings_w` scoped OAuth token and `x-api-key` in the header, and the new state in the request body. For example, an [`updateListing`](https://developers.etsy.com/documentation/reference/#operation/updateListing)\ request might look like the following:\ \ * JavaScript fetch\ * PHP curl\ \ var headers \= new Headers();\ \ headers.append("Content-Type", "application/x-www-form-urlencoded");\ \ headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5");\ \ headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz");\ \ var urlencoded \= new URLSearchParams();\ \ urlencoded.append("shipping\_profile\_id", "6722757781");\ \ var requestOptions \= {\ \ method: 'PATCH',\ \ headers: headers,\ \ body: urlencoded,\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/shops/12345678/listings/192837465", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/shops/12345678/listings/192837465',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'PATCH',\ \ CURLOPT\_POSTFIELDS \=> 'shipping\_profile\_id=6722757781'\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: application/x-www-form-urlencoded',\ \ 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ Adding a processing profile to a listing[#](https://developers.etsy.com/documentation/tutorials/listings#adding-a-processing-profile-to-a-listing "Direct link to heading")\ \ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------\ \ Processing profiles contain information about the readiness state and processing time of a product. Every physical listing requires at least one processing profile to be linked to it. You can create processing profiles for your shop with [`createShopReadinessStateDefinition`](https://developers.etsy.com/documentation/reference/#operation/createShopReadinessStateDefinition)\ , and link it to a listing using the `readiness_state_id` when you create a new listing through [`createDraftListing`](https://developers.etsy.com/documentation/reference#operation/createDraftListing)\ or to specific products when you update a listing's inventory through [`updateListingInventory`](https://developers.etsy.com/documentation/reference#operation/updateListingInventory)\ .\ \ The following procedure creates a new processing profile and returns the `readiness_state_id` in the response:\ \ 1. Form a valid URL for [`createShopReadinessStateDefinition`](https://developers.etsy.com/documentation/reference/#operation/createShopReadinessStateDefinition)\ , which must include a `shop_id`. For example, if your `shop_id` is "12345678", then the [`createShopReadinessStateDefinition`](https://developers.etsy.com/documentation/reference/#operation/createShopReadinessStateDefinition)\ URL is:\ \ [https://api.etsy.com/v3/application/shops/12345678/readiness-state-definitions](https://api.etsy.com/v3/application/shops/12345678/readiness-state-definitions)\ \ 2. Build the [`createShopReadinessStateDefinition`](https://developers.etsy.com/documentation/reference/#operation/createShopReadinessStateDefinition)\ request body, which must include at a minimum:\ \ \ * `readiness_state`: The state a product can be in production wise, values can be either "ready\_to\_ship" or "made\_to\_order".\ * `min_processing_time`: The minimum processing time required to process to ship listings with this shipping profile. This field is in deprecation phase and will be removed by Q1 2026.\ * `max_processing_time`: The maximum processing time required to process to ship listings with this shipping profile. This field is in deprecation phase and will be removed by Q1 2026.\ * `processing_time_unit`: The unit used to represent how long a processing time is. A week is equivalent to 5 business days. Values can be "days" or "weeks". If none is provided, the unit is set to "days".\ \ 3. Execute a [`createShopReadinessStateDefinition`](https://developers.etsy.com/documentation/reference/#operation/createShopReadinessStateDefinition)\ POST request with your `shops_w` scoped OAuth token and `x-api-key`, and read the generated `readiness_state_id` from the response, which you’ll use to link it to specific products later on. For example, a [`createShopReadinessStateDefinition`](https://developers.etsy.com/documentation/reference/#operation/createShopReadinessStateDefinition)\ request for a product that’s made to order and the processing time is 5-8 days might look like the following:\ \ * JavaScript fetch\ * PHP curl\ \ var headers \= new Headers();\ \ headers.append("Content-Type", "application/x-www-form-urlencoded");\ \ headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff");\ \ headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz");\ \ var urlencoded \= new URLSearchParams();\ \ urlencoded.append("readiness\_state", "made\_to\_order");\ \ urlencoded.append("min\_processing\_time", "5");\ \ urlencoded.append("max\_processing\_time", "8");\ \ urlencoded.append("processing\_time\_unit", "days");\ \ var requestOptions \= {\ \ method: 'POST',\ \ headers: headers,\ \ body: urlencoded,\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/shops/12345678/readiness-state-definitions", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/shops/12345678/readiness-state-definitions',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'POST',\ \ CURLOPT\_POSTFIELDS \=> 'readiness\_state=made\_to\_order&min\_processing\_time=5&max\_processing\_time=8&processing\_time\_unit=days'\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: application/x-www-form-urlencoded',\ \ 'x-api-key: 1aa2bb33c44d55eeeeee6fff',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ 4. Set the listing's `readiness_state_id` to the readiness state ID read from the response while creating a new listing through [`createDraftListing`](https://developers.etsy.com/documentation/reference/#operation/createDraftListing)\ endpoint or while updating the listing through [`updateListingInventory`](https://developers.etsy.com/documentation/reference#operation/updateListingInventory)\ endpoint. For example, an [`updateListingInventory`](https://developers.etsy.com/documentation/reference#operation/updateListingInventory)\ request might look like the following:\ \ * JavaScript fetch\ * PHP curl\ \ var headers \= new Headers();\ \ headers.append("Content-Type", "application/json");\ \ headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff");\ \ headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz");\ \ var productsArray \= {\ \ "products": \[\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201056977\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201056977\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ }\ \ \],\ \ "price\_on\_property": \[507\],\ \ "quantity\_on\_property": \[100\],\ \ "sku\_on\_property": \[100\],\ \ "readiness\_state\_on\_property": \[507\],\ \ };\ \ var requestOptions \= {\ \ method: 'PUT',\ \ headers: headers,\ \ body: JSON.stringify(productsArray),\ \ redirect: 'follow'\ \ };\ \ fetch("https://api.etsy.com/v3/application/listings/192837465/inventory", requestOptions)\ \ .then(response \=> response.text())\ \ .then(result \=> console.log(result))\ \ .catch(error \=> console.log('error', error));\ \ Copy\ \ 'https://api.etsy.com/v3/application/listings/192837465/inventory',\ \ CURLOPT\_RETURNTRANSFER \=> true,\ \ CURLOPT\_ENCODING \=> '',\ \ CURLOPT\_MAXREDIRS \=> 10,\ \ CURLOPT\_TIMEOUT \=> 0,\ \ CURLOPT\_FOLLOWLOCATION \=> true,\ \ CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1,\ \ CURLOPT\_CUSTOMREQUEST \=> 'PUT',\ \ CURLOPT\_POSTFIELDS \=>'{\ \ "products": \[\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing4",\ \ "offerings": \[\ \ {\ \ "quantity": 44,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201056977\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107494140\ \ \],\ \ "values": \[\ \ "4"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 8.00,\ \ "readiness\_state\_id": 18201076875\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610620\ \ \],\ \ "values": \[\ \ "Walnut"\ \ \]\ \ }\ \ \]\ \ },\ \ {\ \ "sku": "woodthing5",\ \ "offerings": \[\ \ {\ \ "quantity": 55,\ \ "is\_enabled": true,\ \ "price": 6.00,\ \ "readiness\_state\_id": 18201056977\ \ }\ \ \],\ \ "property\_values": \[\ \ {\ \ "property\_id": 100,\ \ "property\_name": "Size",\ \ "scale\_id": 327,\ \ "value\_ids": \[\ \ 18107397735\ \ \],\ \ "values": \[\ \ "5"\ \ \]\ \ },\ \ {\ \ "property\_id": 507,\ \ "property\_name": "Material",\ \ "scale\_id": null,\ \ "value\_ids": \[\ \ 18163610622\ \ \],\ \ "values": \[\ \ "Pine"\ \ \]\ \ }\ \ \]\ \ }\ \ \],\ \ "price\_on\_property": \[507\],\ \ "quantity\_on\_property": \[100\],\ \ "sku\_on\_property": \[100\]\ \ "readiness\_state\_on\_property": \[507\],\ \ }',\ \ CURLOPT\_HTTPHEADER \=> array(\ \ 'Content-Type: application/json',\ \ 'x-api-key: 1aa2bb33c44d55eeeeee6fff',\ \ 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz'\ \ ),\ \ ));\ \ $response \= curl\_exec($curl);\ \ curl\_close($curl);\ \ echo $response;\ \ Copy\ \ As you can see in the above example, since `processing profiles` vary by the material property like `price`, we'll add a `readiness_state_on_property` value with the property\_id corresponding to "Material" (`507`).\ \ Each product offering will have an associated `readiness_state_id`, in this case the same `readiness_state_id` needs to be used for all the offerings that have the same material. We have two offerings for each material, let’s take “Walnut” as an example:\ \ 1. Walnut - Size 4\ 2. Walnut - Size 5\ \ Since they all share the “Walnut” property value they will use the same processing profile.\ \ However, if you’d prefer to set the processing profile at a listing level, the body request for the [updateListingInventory](https://developers.etsy.com/documentation/reference#operation/updateListingInventory)\ endpoint would be pretty similar to the case above, with two main differences:\ \ 1. The same `readiness_state_id` will be used for all the product offerings.\ 2. The `readiness_state_on_property` value will be empty, as none of the properties change the readiness state of the product.\ \ * [`Authorization` and `x-api-key` header parameters](https://developers.etsy.com/documentation/tutorials/listings#authorization-and-x-api-key-header-parameters)\ \ * [Listing lifecycle and state](https://developers.etsy.com/documentation/tutorials/listings#listing-lifecycle-and-state)\ \ * [Listing a physical product for sale](https://developers.etsy.com/documentation/tutorials/listings#listing-a-physical-product-for-sale)\ \ * [Listing a digital product for sale](https://developers.etsy.com/documentation/tutorials/listings#listing-a-digital-product-for-sale)\ \ * [Converting a physical product listing to a digital product listing](https://developers.etsy.com/documentation/tutorials/listings#converting-a-physical-product-listing-to-a-digital-product-listing)\ \ * [Adding an image to a listing](https://developers.etsy.com/documentation/tutorials/listings#adding-an-image-to-a-listing)\ \ * [Listing inventory with different properties, quantities, and prices](https://developers.etsy.com/documentation/tutorials/listings#listing-inventory-with-different-properties-quantities-and-prices)\ * [Updating Inventory](https://developers.etsy.com/documentation/tutorials/listings#updating-inventory)\ \ * [Handling Variations in Inventory Updates](https://developers.etsy.com/documentation/tutorials/listings#handling-variations-in-inventory-updates)\ \ * [Custom Variations](https://developers.etsy.com/documentation/tutorials/listings#custom-variations)\ \ * [How to Fetch Property Values for the `Products` Array?](https://developers.etsy.com/documentation/tutorials/listings#how-to-fetch-property-values-for-the-products-array)\ \ * [Adding a shipping profile to a listing](https://developers.etsy.com/documentation/tutorials/listings#adding-a-shipping-profile-to-a-listing)\ \ * [Adding a processing profile to a listing](https://developers.etsy.com/documentation/tutorials/listings#adding-a-processing-profile-to-a-listing) --- # Payments Tutorial | Etsy Open API v3 ##### important These tutorials are subject to change as endpoints change during our feedback period development. We welcome your feedback! If you find an error or have a suggestion, please post it in the [Open API GitHub Repository](https://github.com/etsy/open-api) . Payments and the Shop Ledger contain financial information for your shop's transactions. The Open API v3 endpoints for payments and the shop ledger are read-only operations — as buyers make purchases, sellers post shipping costs with the listing, and refunds are not automatic. The API implements payments and the shop ledger to support reporting, receipt management, fees, and taxes. The differences between these two resources are: 1. a shop payment account ledger entry, identified by `entry_id` and `ledger_id`, represents the total payment account value after each debit or credit to the shop's payment account, including transactions made for purchases and fulfillment. This is similar to the running total in a bank account and you access it using the [getShopPaymentAccountLedgerEntries](https://developers.etsy.com/documentation/reference/#tag/Ledger-Entry) endpoint. See [Reading a shop payment account ledger](https://developers.etsy.com/documentation/tutorials/payments#reading-a-shop-payment-account-ledger) below. 2. a payment, identified by`payment_id` or `receipt_id`, represents all the payment details for a purchase after [fulfillment](https://developers.etsy.com/documentation/tutorials/payments/fulfillment) , including fees, shipping, and taxes. This tells you how much a buyer paid, how Etsy divides up the payment to cover costs, and the payment method. You can access payments using the [getPayments](https://developers.etsy.com/documentation/reference/#operation/getPayments) endpoint. See [Viewing payments](https://developers.etsy.com/documentation/tutorials/payments#viewing-payments) below. For example, when a buyer pays for a purchase, an entry appears in the shop payment account ledger, but there is no payment record until the purchase ships. _Throughout this tutorial, the instructions reference REST resources, endpoints, parameters, and response fields, which we cover in detail in [Request Standards](https://developers.etsy.com/documentation/tutorials/essentials/requests) and [URL Syntax](https://developers.etsy.com/documentation/tutorials/essentials/urlsyntax) ._ ### `Authorization` and `x-api-key` header parameters[#](https://developers.etsy.com/documentation/tutorials/payments#authorization-and-x-api-key-header-parameters "Direct link to heading") The endpoints in this tutorial require an OAuth token in the header with `transactions_r` scope. See the [Authentication topic](https://developers.etsy.com/documentation/tutorials/essentials/authentication) for instructions on how to generate an OAuth token with these scopes. In addition, all Open API V3 requests require the `x-api-key:` parameter in the header with your shop's Etsy App API Key _keystring_ and _shared secret_, separated by a colon (`:`), which you can find in [Your Apps](https://www.etsy.com/developers/your-apps) . Reading a shop payment account ledger[#](https://developers.etsy.com/documentation/tutorials/payments#reading-a-shop-payment-account-ledger "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Each change in the shop payment account is recorded in an entry in the shop payment account ledger. This includes individual charges and payments recorded at the time they executed. For example, when you pay to renew a listing, Etsy adds an entry to the shop payment account ledger. The following procedure displays all entries in a shop payment account ledger, 25 entries at a time, in chronological order: 1. Form a valid URL for [getShopPaymentAccountLedgerEntries](https://developers.etsy.com/documentation/reference/#tag/Ledger-Entry) , which must include a `shop_id` for the shop. For example, if your shop\_id is 12345678, the getShopPaymentAccountLedgerEntries URL is: https://api.etsy.com/v3/application/shops/12345678/payment-account/ledger-entries Copy 2. Add the query parameters to get all entries, 25 at a time: ?min\_created=NaN&max\_created=NaN&limit=25&offset=0 Copy 3. Execute a getShopPaymentAccountLedgerEntries GET request with a `transactions_r` scope OAuth token and `x-api-key`, which might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var requestOptions \= { method: 'GET', headers: headers, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/payment-account/ledger-entries?min\_created=NaN&max\_created=NaN&limit=25&offset=0", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/payment-account/ledger-entries?min\_created=NaN&max\_created=NaN&limit=25&offset=0', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'GET', CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy Viewing payments[#](https://developers.etsy.com/documentation/tutorials/payments#viewing-payments "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------- After [shipping a purchase](https://developers.etsy.com/documentation/tutorials/payments/fulfillment) , a buyer's payment posts to the shop and the receipt updates to reflect the changes due to shipping, taxes, and fees. While the receipt contains only the details most useful to the buyer, the payment contains the monetary details of the transaction, such as the currency the buyer used, and the currencies used to pay fees, taxes, and shipping costs. The following procedure displays all payments posted to an Etsy shop: 1. Form a valid URL for [getPayments](https://developers.etsy.com/documentation/reference/#operation/getPayments) , which must include a `shop_id` for the shop. For example, if your shop\_id is 12345678, the getPayments URL is: https://api.etsy.com/v3/application/shops/12345678/payments Copy 2. Execute a getPayments GET request with a `transactions_r` scope OAuth token and `x-api-key`, which might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var requestOptions \= { method: 'GET', headers: headers, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/payments", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678/payments', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'GET', CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy Viewing a payment associated with a specific ledger entry[#](https://developers.etsy.com/documentation/tutorials/payments#viewing-a-payment-associated-with-a-specific-ledger-entry "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- When you have ledger entries and want to know which payments included them, send a [getPaymentAccountLedgerEntryPayments](https://developers.etsy.com/documentation/reference/#operation/getPaymentAccountLedgerEntryPayments) request including the `ledger_id`. For ledger entries for debits and credits involved in a payment, the response includes the payment details. The response is empty for ledger entries not included in a payment. The following procedure displays all payments posted to an Etsy shop: 1. Form a valid URL for [getPaymentAccountLedgerEntryPayments](https://developers.etsy.com/documentation/reference/#operation/getPaymentAccountLedgerEntryPayments) , which must include a `shop_id` for the shop. For example, if your shop\_id is 12345678, the getPayments URL is: https://api.etsy.com/v3/application/shops/12345678/payment-account/ledger-entries/payments Copy 2. Add the query parameters to get the payments associated with specific ledger entries. For example, to get the payments associated with ledger entry IDs 42362821 and 42362821, the query parameters would be: ?ledger\_entry\_ids=42362821,69507139 Copy 3. Execute a getPaymentAccountLedgerEntryPayments GET request with a `transactions_r` scope OAuth token and `x-api-key`, which might look like the following: * JavaScript fetch * PHP curl var headers \= new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("x-api-key", "1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5"); headers.append("Authorization", "Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz"); var requestOptions \= { method: 'GET', headers: headers, redirect: 'follow' }; fetch("https://api.etsy.com/v3/application/shops/12345678/payment-account/ledger-entries/payments?ledger\_entry\_ids=42362821%2C69507139", requestOptions) .then(response \=> response.text()) .then(result \=> console.log(result)) .catch(error \=> console.log('error', error)); Copy 'https://api.etsy.com/v3/application/shops/12345678/payment-account/ledger-entries/payments?ledger\_entry\_ids=42362821%2C69507139', CURLOPT\_RETURNTRANSFER \=> true, CURLOPT\_ENCODING \=> '', CURLOPT\_MAXREDIRS \=> 10, CURLOPT\_TIMEOUT \=> 0, CURLOPT\_FOLLOWLOCATION \=> true, CURLOPT\_HTTP\_VERSION \=> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST \=> 'GET', CURLOPT\_HTTPHEADER \=> array( 'Content-Type: application/x-www-form-urlencoded', 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5', 'Authorization: Bearer 12345678.jKBPLnOiYt7vpWlsny\_lDKqINn4Ny\_jwH89hA4IZgggyzqmV\_bmQHGJ3HOHH2DmZxOJn5V1qQFnVP9bCn9jnrggCRz' ), )); $response \= curl\_exec($curl); curl\_close($curl); echo $response; Copy * [`Authorization` and `x-api-key` header parameters](https://developers.etsy.com/documentation/tutorials/payments#authorization-and-x-api-key-header-parameters) * [Reading a shop payment account ledger](https://developers.etsy.com/documentation/tutorials/payments#reading-a-shop-payment-account-ledger) * [Viewing payments](https://developers.etsy.com/documentation/tutorials/payments#viewing-payments) * [Viewing a payment associated with a specific ledger entry](https://developers.etsy.com/documentation/tutorials/payments#viewing-a-payment-associated-with-a-specific-ledger-entry) --- # Authentication | Etsy Open API v3 Etsy's Open API supports OAuth 2.0 [Authorization Code Grants](https://tools.ietf.org/html/rfc6749#page-24) to generate OAuth tokens for app security. Authorization code grants require users to approve access, which generates an authorization code an app includes in a token request (`https://api.etsy.com/v3/public/oauth/token`) from the [OAuth resource](https://developers.etsy.com/documentation/reference#section/Authentication/oauth2) . [OAuth 2.0](https://tools.ietf.org/html/rfc6749) is fairly well-standardized, so this document focuses on Etsy’s specific implementation of OAuth2. Requesting an OAuth Token[#](https://developers.etsy.com/documentation/essentials/oauth2/#requesting-an-oauth-token "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------------------------------- Gather the following information before starting the **authorization code** grant flow: 1. Your Etsy App API Key _keystring_, which you can find in [Your Apps](https://www.etsy.com/developers/your-apps) . 2. A _callback URL_ your app uses to receive the authorization code. Typically, this is a page or script that starts the token request using the authorization code, and therefore must implement TLS and use an `https://` prefix. See [Redirect URIs](https://developers.etsy.com/documentation/essentials/oauth2/#redirect-uris) below. 3. The _scopes_ your application requires to use specific endpoints. The [Open API Reference](https://developers.etsy.com/documentation/reference) lists the authorizations required to use each endpoint. For example, the endpoint to [create a listing](https://developers.etsy.com/documentation/reference#operation/createDraftListing) requires an oauth2 token with `listings_w` scope. See [Scopes](https://developers.etsy.com/documentation/essentials/oauth2/#scopes) below. 4. A _state_ string, similar to a [strong password](https://techjury.net/blog/how-to-create-a-strong-password) , which protects against [Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery) exploits. 5. A _code verifier_ and generated _code challenge_ proof key for code exchange (PKCE) pair required in the token request and authorization code request respectively. See [PKCE](https://developers.etsy.com/documentation/essentials/oauth2/#proof-key-for-code-exchange-pkce) below. ### Step 1: Request an Authorization Code[#](https://developers.etsy.com/documentation/essentials/oauth2/#step-1-request-an-authorization-code "Direct link to heading") To begin the flow, direct the user to `https://www.etsy.com/oauth/connect` with a GET request including the following URL parameters: | Parameter Name | Description | | --- | --- | | `response_type` | Must always be the value `code` (no quotes). | | `client_id` | An Etsy App API Key _keystring_ for the app. | | `redirect_uri` | A URI your app uses to receive the authorization code or error message; see [Redirect URIs](https://developers.etsy.com/documentation/essentials/oauth2/#redirect-uris)
below. The URL must have the `https://` prefix or the request will fail. | | `scope` | A URL-encoded, space-separated list of one or more scopes (e.g., `shops_r%20shops_w`); see [Scopes](https://developers.etsy.com/documentation/essentials/oauth2/#scopes)
below. | | `state` | The state parameter must be non-empty and should be a single-use token generated specifically for a given request. It is important that the state parameter is impossible to guess, associated with a specific request, and used once. Use _state_ for [CSRF protection](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
. | | `code_challenge` | The PKCE _code challenge_ SHA256-image of a random value for this request flow; see [PKCE](https://developers.etsy.com/documentation/essentials/oauth2/#proof-key-for-code-exchange-pkce)
below. | | `code_challenge_method` | Must always be the value `S256` (no quotes). | For example, to request an authorization code for an Etsy app with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff`, initiate a GET request with the following URL: https://www.etsy.com/oauth/connect? response\_type=code &redirect\_uri=https://www.example.com/some/location &scope=transactions\_r%20transactions\_w &client\_id=1aa2bb33c44d55eeeeee6fff&state=superstate &code\_challenge=DSWlW2Abh-cf8CeLL8-g3hQ2WQyYdKyiu83u\_s7nRhI &code\_challenge\_method=S256 Copy where: * `response_type=code` is required to request an authorization code. * `redirect_uri=https://www.example.com/some/location` directs etsy to send an authorization code response to `https://www.example.com/some/location`. * `scope=transactions_r%20transactions_w` adds read and write access to transactions in the authorization _scope_ for the request, which is required to [request shop receipts](https://developers.etsy.com/documentation/reference#operation/getShopReceipts) . see [Scopes](https://developers.etsy.com/documentation/essentials/oauth2/#scopes) below. * `client_id=1aa2bb33c44d55eeeeee6fff` is an API Key _keystring_ for the app. * `state=superstate` assigns the _state_ string to `superstate` which Etsy.com should return with the authorization code * `code_challenge=DSWlW2Abh-cf8CeLL8-g3hQ2WQyYdKyiu83u_s7nRhI` is the PKCE _code challenge_ generated from the _code verifier_ `vvkdljkejllufrvbhgeiegrnvufrhvrffnkvcknjvfid`, which must be in the OAuth token request with the authorization code. * `code_challenge_method=S256` is required to correctly interpret the _code\_challenge_. ### Step 2: Grant Access[#](https://developers.etsy.com/documentation/essentials/oauth2/#step-2-grant-access "Direct link to heading") If the authorization code request is valid, Etsy.com responds by prompting an Etsy.com user (typically the app user) to grant the application access the requested scopes. ![OAuth2 authorization confirmation page](https://img0.etsystatic.com/site-assets/open-api/oauth2-authorize.png) If the user grants access, Etsy.com sends a request back to the app's `redirect_uri` with the following `GET` parameters: | Parameter Name | Description | | --- | --- | | `state` | The _state_ parameter, exactly as set in the authorization request | | `code` | An OAuth _authorization code_ required to request an OAuth token | For example, the following response indicates that the user grants access and supplies an authorization code: https://www.example.com/some/location? code=bftcubu-wownsvftz5kowdmxnqtsuoikwqkha7\_4na3igu1uy-ztu1bsken68xnw4spzum8larqbry6zsxnea4or9etuicpra5zi &state=superstate Copy Before using an _authorization code_, validate that the _state_ string in the response matches the _state_ sent with the authorization code request. If they do not match, halt authentication as the request is vulnerable to CSRF attacks. If they match, make a note never to use that _state_ again, and make your next authorization code request with a new _state_ string. #### Errors[#](https://developers.etsy.com/documentation/essentials/oauth2/#errors "Direct link to heading") If the user does not consent, or there is some other error (e.g. a missing parameter), Etsy.com sends a response to the specified `redirect_uri` with the following `GET` parameters: | Parameter Name | Description | | --- | --- | | `state` | The _state_ parameter, exactly as set in the authorization request | | `error` | An error code from [RFC 6749](https://tools.ietf.org/html/rfc6749#section-5.2) | | `error_description` | A human-readable explanation of the error (always in English) | | `error_uri` | (Optional) A URL with more information about the error. | ### Step 3: Request an Access Token[#](https://developers.etsy.com/documentation/essentials/oauth2/#step-3-request-an-access-token "Direct link to heading") Request an OAuth access token using the _authorization code_ in a POST request to the Etsy Open API `/oauth/token` resource. Most requests to the Etsy Open API require this access token, which has a functional life of 1 hour. The Etsy Open API delivers a [refresh token](https://developers.etsy.com/documentation/essentials/oauth2/#Refreshing-an-OAuth-Token) with the access token, which you can use to obtain a new access token through the [refresh\_token grant](https://tools.ietf.org/html/rfc6749#section-6) , and has a longer functional lifetime (90 days). To obtain an access token, make a POST request to `https://api.etsy.com/v3/public/oauth/token` with the following parameters in the request body in `application/x-www-form-urlencoded` format: | Parameter Name | Description | | --- | --- | | `grant_type` | Must always be the value `authorization_code` | | `client_id` | An Etsy App API Key _keystring_ for the app. | | `redirect_uri` | The same `redirect_uri` value used in the prior authorization code request. | | `code` | The _authorization code_ sent back from Etsy.com after [granting access](https://developers.etsy.com/documentation/essentials/oauth2/#step-2-grant-access)
. | | `code_verifier` | The PKCE _code verifier_ preimage of the `code_challenge` used in the prior authorization code request; see [PKCE](https://developers.etsy.com/documentation/essentials/oauth2/#proof-key-for-code-exchange-pkce)
below. | For example, to request access for an Etsy app with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff`, initiate a POST request: https://api.etsy.com/v3/public/oauth/token? grant\_type=authorization\_code &client\_id=1aa2bb33c44d55eeeeee6fff &redirect\_uri=https://www.example.com/some/location &code=bftcubu-wownsvftz5kowdmxnqtsuoikwqkha7\_4na3igu1uy-ztu1bsken68xnw4spzum8larqbry6zsxnea4or9etuicpra5zi &code\_verifier=vvkdljkejllufrvbhgeiegrnvufrhvrffnkvcknjvfid Copy where: * `grant_type=authorization_code` is required to request an OAuth token in an authorization token grant flow. * `client_id=1aa2bb33c44d55eeeeee6fff` is an API Key _keystring_ for the app. * `redirect_uri=https://www.example.com/some/location` directs etsy to send the access token response to `https://www.example.com/some/location`. * `code=bftcubu-wownsvftz5kowdmxnqtsuoikwqkha7_4na3igu1uy-ztu1bsken68xnw4spzum8larqbry6zsxnea4or9etuicpra5zi` is the authorization code sent from Etsy.com after the user grants access * `code_verifier=vvkdljkejllufrvbhgeiegrnvufrhvrffnkvcknjvfid` is the PKCE _code verifier_ used to generate the _code challenge_ `DSWlW2Abh-cf8CeLL8-g3hQ2WQyYdKyiu83u_s7nRhI`, which we used in the authorization code request. The Etsy Open API responds to an authentic request for an OAuth token with the following information in JSON format: { "access\_token": "12345678.O1zLuwveeKjpIqCQFfmR-PaMMpBmagH6DljRAkK9qt05OtRKiANJOyZlMx3WQ\_o2FdComQGuoiAWy3dxyGI4Ke\_76PR", "token\_type": "Bearer", "expires\_in": 3600, "refresh\_token": "12345678.JNGIJtvLmwfDMhlYoOJl8aLR1BWottyHC6yhNcET-eC7RogSR5e1GTIXGrgrelWZalvh3YvvyLfKYYqvymd-u37Sjtx" } Copy where: * `access_token` is the OAuth grant token with a user id numeric prefix (`12345678` in the example above), which is the internal `user_id` of the Etsy.com user who grants the application access. The V3 Open API requires the combined user id prefix and OAuth token as formatted in this parameter to authenticate requests. * * * NOTE: This numeric OAuth `user_id` is only available from the authorization code grant flow * * * * `token_type` is always `Bearer` which indicates that the OAuth token is a bearer token. * `expires_in` is the valid duration of the OAuth token in seconds from the moment it is granted; 3600 seconds is 1 hour. * `refresh_token` is the OAuth code to request a refresh token with a user id numeric prefix (`12345678` in the example). Use this for a refresh grant access request for a fresh OAuth token without requesting access from the user/seller an additional time. Redirect URIs[#](https://developers.etsy.com/documentation/essentials/oauth2/#redirect-uris "Direct link to heading") ---------------------------------------------------------------------------------------------------------------------- All `redirect_uri` parameter values must match a precise _callback URL_ string registered with Etsy. These values can be provided by editing your application at [etsy.com/developers/your-apps](https://www.etsy.com/developers/your-apps) . Authorization code or token requests with unregistered or non-matching `redirect_uri` values send an error to the user and Etsy.com does **not** redirect the user back to your app. URL matching is case-sensitive and is specifically the URL established when you registered. For example, if your registered redirect URL is `https://www.example.com/some/location`, the following strings **fail** to match: * `http://www.example.com/some/location` (http, not https) * `https://www.example.com/some/location/` (additional trailing slash) * `https://www.example.com/some/location?` (additional trailing question mark) * `Https://www.example.com/some/location` (uppercase H in https) * `https://example.com/some/location` (no www subdomain) Scopes[#](https://developers.etsy.com/documentation/essentials/oauth2/#scopes "Direct link to heading") -------------------------------------------------------------------------------------------------------- Methods and fields in the Etsy API are tagged with "permission scopes" that control which operations an app can perform and which data an app can read with a given set of credentials. Scopes are the permissions you request from the user, and the access token proves you have permission to act from that user. The following scopes are available at this time, though are subject to change. The availability of a scope does not necessarily imply the existence of an endpoint to perform that action. Each API endpoint may require zero, one, or more scopes for access. Consult the [Open API Reference](https://developers.etsy.com/documentation/reference) to determine the scopes required for each specific endpoint. | Name | Description | | --- | --- | | `address_r` | Read a member's shipping addresses. | | `address_w` | Update and delete a member's shipping address. | | `billing_r` | Read a member's Etsy bill charges and payments. | | `cart_r` | Read the contents of a member’s cart. | | `cart_w` | Add and remove listings from a member's cart. | | `email_r` | Read a user profile | | `favorites_r` | View a member's favorite listings and users. | | `favorites_w` | Add to and remove from a member's favorite listings and users. | | `feedback_r` | View all details of a member's feedback (including purchase history.) | | `listings_d` | Delete a member's listings. | | `listings_r` | Read a member's inactive and expired (i.e., non-public) listings. | | `listings_w` | Create and edit a member's listings. | | `profile_r` | Read a member's private profile information. | | `profile_w` | Update a member's private profile information. | | `recommend_r` | View a member's recommended listings. | | `recommend_w` | Remove a member's recommended listings. | | `shops_r` | See a member's shop description, messages and sections, even if not (yet) public. | | `shops_w` | Update a member's shop description, messages and sections. | | `transactions_r` | Read a member's purchase and sales data. This applies to buyers as well as sellers. | | `transactions_w` | Update a member's sales data. | Scopes are associated with every access token, and any change in scope requires the user to re-authorize the application; to change scopes, you must go through the authorization code grant flow again. Conversely, users are generally less likely to authorize an application that makes a request for more scopes than it requires. As such, you should carefully tailor scope requests to your application. To request multiple scopes, add them in a space-separated list. For example, to request the scopes to see a user’s shipping addresses and email address, add the `email_r%20address_r` strings for the scope parameter in the request for an authentication code. Proof Key for Code Exchange (PKCE)[#](https://developers.etsy.com/documentation/essentials/oauth2/#proof-key-for-code-exchange-pkce "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------------------------------- A Proof Key for Code Exchange (PKCE) is the implementation of an OAuth2 extension standardized in RFC 7636 that guarantees that an authorization code is valid for only one application and cannot be intercepted by the user or an attacker. The Etsy Open API requires a PKCE on every authorization flow request. A PKCE works by using a code **verifier** , which must be a high-entropy random string consisting of between 43 and 128 characters from the range `[A-Za-z0-9._~-]` (i.e. unreserved URI characters). You can generate an appropriate verifier using a cryptographically secure source of randomness and encode 32 bytes of random data into url-safe base 64. Store this value in association with a particular authorization code request. Then construct a code **challenge** by taking the URL-safe base64-encoded output of the SHA256 hash of the code verifier, and use it in the authorization code request to `https://www.etsy.com/oauth/connect`. You must provide the verifier in the request for an access token from the Etsy API server, which proves that you are the source of the original authorization request. For an example of how to generate a code verifier and matching challenge, see [Appendix B of RFC 7636](https://tools.ietf.org/html/rfc7636#appendix-B) . Requesting a Refresh OAuth Token[#](https://developers.etsy.com/documentation/essentials/oauth2/#requesting-a-refresh-oauth-token "Direct link to heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------ Etsy's Open API supports OAuth 2.0 [Refresh Grants](https://datatracker.ietf.org/doc/html/rfc6749#section-1.5) to generate OAuth tokens after the seller grants a user an initial Authorization Code grant token. Refresh tokens do not require sellers to re-approve access and have the same scope as the token granted by the initial Authorization Code grant token. You cannot change the scope of a refresh token from the scope established in the initial Authentication Grant token. To obtain a refresh token, make a POST request to `https://api.etsy.com/v3/public/oauth/token` with the following parameters in the request body in `application/x-www-form-urlencoded` format: | Parameter Name | Description | | --- | --- | | `grant_type` | Must be the value `refresh_token` | | `client_id` | An Etsy App API Key _keystring_ for the app. | | `refresh_token` | The _refresh token_ string sent with a prior Authorization Code Grant or Refresh Grant. | For example, to request a refresh token for an Etsy app with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff`, initiate a POST request: https://api.etsy.com/v3/public/oauth/token? grant\_type=refresh\_token &client\_id=1aa2bb33c44d55eeeeee6fff &refresh\_token=12345678.JNGIJtvLmwfDMhlYoOJl8aLR1BWottyHC6yhNcET-eC7RogSR5e1GTIXGrgrelWZalvh3YvvyLfKYYqvymd-u37Sjtx Copy where: * `grant_type=refresh_code` is required to request an OAuth token in a refresh grant context. * `client_id=1aa2bb33c44d55eeeeee6fff` is an API Key _keystring_ for the app. * `refresh_token=12345678.JNGIJtvLmwfDMhlYoOJl8aLR1BWottyHC6yhNcET-eC7RogSR5e1GTIXGrgrelWZalvh3YvvyLfKYYqvymd-u37Sjtx` is the refresh code sent from Etsy.com after granting a prior authorization grant token or refresh grant token. The Etsy Open API responds to an authentic request for an OAuth token with the following information in JSON format: { "access\_token": "12345678.O1zLuwveeKjpIqCQFfmR-PaMMpBmagH6DljRAkK9qt05OtRKiANJOyZlMx3WQ\_o2FdComQGuoiAWy3dxyGI4Ke\_76PR", "token\_type": "Bearer", "expires\_in": 3600, "refresh\_token": "12345678.JNGIJtvLmwfDMhlYoOJl8aLR1BWottyHC6yhNcET-eC7RogSR5e1GTIXGrgrelWZalvh3YvvyLfKYYqvymd-u37Sjtx" } Copy where: * `access_token` is the OAuth refresh code with a user id numeric prefix (`12345678` in the example above), which is the internal `user_id` of the Etsy.com user who grants the application access. * `token_type` is always `Bearer` which indicates that the OAuth token is a bearer token. * `expires_in` is the valid duration of the OAuth token in seconds from the moment it is granted; 3600 seconds is 1 hour. * `refresh_token` is the OAuth code to request another refresh token with a user id numeric prefix (`12345678` in the example). Use this for a refresh grant access request for a fresh OAuth token without requesting access from the user/seller an additional time. APIv2 Endpoints and OAuth2 Tokens[#](https://developers.etsy.com/documentation/essentials/oauth2/#apiv2-endpoints-and-oauth2-tokens "Direct link to heading") -------------------------------------------------------------------------------------------------------------------------------------------------------------- Requests to v2 endpoints cannot use tokens generated through the OAuth 2.0 flow described above. Requests to v3 endpoints must use OAuth 2.0 tokens. See [Exchange OAuth 1.0 Token for OAuth 2.0 Token](https://developers.etsy.com/documentation/essentials/authentication/#exchange-oauth-10-token-for-oauth-20-token) to upgrade existing tokens. ### Scopes changed for OAuth 1.0 in the V3 Open API[#](https://developers.etsy.com/documentation/essentials/oauth2/#scopes-changed-for-oauth-10-in-the-v3-open-api "Direct link to heading") The V3 Open API supports most of the same scopes for OAuth 1.0 that were supported in V2. However, the following scopes are different from the scopes supported for V2, so you should update them if you use them: 1. Several combined read and write scopes from v2 are split into separate read scopes and write scopes in v3 | V2 scope | V3 scopes | Description | Affected Resources | | --- | --- | --- | --- | | `favorites_rw` | `favorites_r` | View a member's favorite listings and users. | FavoriteListing and FavoriteUser | | | `favorites_w` | Add to and remove from a member's favorite listings and users. | FavoriteListing and FavoriteUser | | `shops_rw` | `shops_r` | View a member's shop description, messages and ections. | Shop and ShopSection | | | `shops_w` | Update a member's shop description, messages and sections. | Shop and ShopSection | | `cart_rw` | `cart_r` | View listings from a member's shopping cart. | Cart and CartListing | | | `cart_w` | Add and remove listings from a member's shopping cart. | Cart and CartListing | | `recommend_rw` | `recommend_r` | View a member's recommended listings. | Listing | | | `recommend_w` | Accept and reject a member's recommended listings. | Listing | 2. `collection_rw`, `page_collection_rw`, and `activity_r` are not implemented because no active end points use them. 3. `treasury_r` and `treasury_w` are not valid because we discontinued the treasury feature. ### Exchange OAuth 1.0 Token for OAuth 2.0 Token[#](https://developers.etsy.com/documentation/essentials/oauth2/#exchange-oauth-10-token-for-oauth-20-token "Direct link to heading") Etsy now supports OAuth 2.0 and existing Open API v3 applications that use OAuth 1.0 must either exchange their OAuth 1.0 access tokens for OAuth 2.0 access tokens or generate OAuth 2.0 access tokens using the OAuth 2.0 Authentication Code flow to use Open API v3 endpoints. To exchange an OAuth 1.0 token for a new OAuth 2.0 token, make a POST request to `https://api.etsy.com/v3/public/oauth/token` with the following parameters in the request body in `application/x-www-form-urlencoded` format: | Parameter Name | Description | | --- | --- | | `grant_type` | Must be the value `token_exchange` | | `client_id` | An Etsy App API Key _keystring_ for the app. | | `legacy_token` | The _legacy token_ is the current OAuth 1.0 token used by the application. | For example, to exchange an access for a new OAuth 2.0 access token on an Etsy app with an App API Key _keystring_ of `1aa2bb33c44d55eeeeee6fff` and legacy token of `eeb39b80e3f43a4671b00dbedaa74e`, initiate a POST request: https://api.etsy.com/v3/public/oauth/token? grant\_type=token\_exchange &client\_id=1aa2bb33c44d55eeeeee6fff &legacy\_token=eeb39b80e3f43a4671b00dbedaa74e Copy The Etsy Open API responds to an authentic token exchange request with the following information in JSON format: { "access\_token": "14099992.HZ3dHl\_DTh-mhPntSLRPg\_Q6hb2S9hsWsX8T-DxkEyzxYzFNFjhl7GsNhS8sps03RVDWlHttE8\_0Am9aA4dy9Xztwdz", "token\_type": "Bearer", "expires\_in": 3600, "refresh\_token": "14099992.nJME1eWEAMw0asH3PG\_mYilsD9neDny5x5WXF3FRIBXW\_xylVH0sILgbu2ER7TQRCmBdluHakZdffPF7qEtQ0kBlWb8" } Copy **Note:** OAuth 2.0 tokens generated from an OAuth 1.0 token exchange retain the scope(s) of the original OAuth 1.0 token. * [Requesting an OAuth Token](https://developers.etsy.com/documentation/essentials/oauth2/#requesting-an-oauth-token) * [Step 1: Request an Authorization Code](https://developers.etsy.com/documentation/essentials/oauth2/#step-1-request-an-authorization-code) * [Step 2: Grant Access](https://developers.etsy.com/documentation/essentials/oauth2/#step-2-grant-access) * [Step 3: Request an Access Token](https://developers.etsy.com/documentation/essentials/oauth2/#step-3-request-an-access-token) * [Redirect URIs](https://developers.etsy.com/documentation/essentials/oauth2/#redirect-uris) * [Scopes](https://developers.etsy.com/documentation/essentials/oauth2/#scopes) * [Proof Key for Code Exchange (PKCE)](https://developers.etsy.com/documentation/essentials/oauth2/#proof-key-for-code-exchange-pkce) * [Requesting a Refresh OAuth Token](https://developers.etsy.com/documentation/essentials/oauth2/#requesting-a-refresh-oauth-token) * [APIv2 Endpoints and OAuth2 Tokens](https://developers.etsy.com/documentation/essentials/oauth2/#apiv2-endpoints-and-oauth2-tokens) * [Scopes changed for OAuth 1.0 in the V3 Open API](https://developers.etsy.com/documentation/essentials/oauth2/#scopes-changed-for-oauth-10-in-the-v3-open-api) * [Exchange OAuth 1.0 Token for OAuth 2.0 Token](https://developers.etsy.com/documentation/essentials/oauth2/#exchange-oauth-10-token-for-oauth-20-token) ---