Have a question? We've gathered some of the most frequent inquiries to provide you with a fast solution.
No, you don't. The credentials (Client ID and Client Secret) are for your application, not for each user you manage through the API. Your entire application will only need a single credential and with that credentials, you can generate access tokens for each user that authorizes your application.
The access_token is short-lived. When it expires, use the refresh_token to obtain a new access_token. Each successful refresh returns both a new access_token and a new refresh_token. Your application must store the new refresh token and discard the previous one.
The refresh_token has a maximum lifetime. If you encounter an invalid_grant error, it usually means the refresh token has expired or no longer valid due to any other reason.
Your strategy should be to securely store the access_token and refresh_token pair for each individual user.
- For web applications: Tokens should be managed correctly within the application's session (e.g., using secure cookies) and should never be stored in a database. When the
access_tokenexpires, use therefresh_tokento get a new pair of tokens with user interaction only when the refresh token expires - For background/batch applications: It's acceptable to store the tokens securely in a database, a secrets manager, or another secure system. The application can then use the
refresh_tokento get a new token pair when the current one expires.
In both cases, you must ensure your storage solution is robust and secure.
Make sure your request includes a valid User-Agent header. Some clients or middleware might leave it out by default, which can cause the request to be rejected.
Use the state parameter. In your initial request, send a unique value in this parameter. When we send the callback, it will include the exact same value. This lets you match the callback to your original request and identify the correct user.
This error generally means the authorization code is no longer valid, either because it has already been used or it has expired. You must use the code immediately after receiving it and only once.
Two flows exist depending on how you integrate:
- Aggregator flow (OAuth 2.0 Authorization Code + PKCE): for partners integrating multiple end-user accounts. Requires you to host a redirect URI and manage the full OAuth handshake. This is what most partners use. The Authentication Guide covers it end to end.
- Direct integrator flow: for partners with a commercial subscription integrating their own single account. You log into a hosted portal, get a refresh token, and use it from your backend. No client secret, no redirect URI. See the Direct Integrator Authentication guide.
If you're building a SaaS that manages your customers' accounts, you're an aggregator. If you're a single business using our APIs for your own storefront, you're a direct integrator.
Direct-integrator refresh tokens are valid for 180 days from issuance, and rotate on every use. Each /token call returns a new refresh token that replaces the one you just used. If you don't refresh within 180 days, or if the session is revoked, you must log back into the portal to get a new one.
Most likely one of:
- You submitted a refresh token that had already been used. Rotation is enforced: presenting a rotated-away token is treated as a compromise signal and revokes the entire session. All refresh tokens issued from that login are invalidated — including the one you thought was current. Recovery: log back into the portal to obtain a fresh refresh token.
- The refresh token expired. They last 180 days from issuance. Log in again on the portal.
Your subscription has a specific limit on the number of active items you can showcase simultaneously.If you publish an item that exceeds this limit, the API will successfully create the item (returning a 201 Created), but it will automatically set its status to Inactive. To make it visible, you must first free up a slot in your plan by deactivating, deleting, or marking another item as sold.
You have two options depending on your needs:
- To view ONLY hidden items: Use the
GET /items/inactiveendpoint. This is the most efficient way to see what is currently hidden. - To view ALL items: Use the
GET /itemsendpoint. In the JSON response, check for theinactivefield. If the objectinactive: { "flag": true }is present, the item is hidden.
Yes! To simplify synchronization between your database and Wallapop, you can map your identifiers using specific attributes during the item creation (POST) or update (PUT) process:
external_id: Use this attribute to store your internal SKU or unique ID. It is available for all categories.license_plate: Use this attribute specifically for vehicle identification in the Cars category.
If your subscription is full but you need to promote a new item, you must free up a slot first. However, choose your action carefully before simply deactivating an item:
Free up a slot (Choose the right method):
- Sold: If the item was sold outside Wallapop, use
PUT /items/{id}/sold. This is crucial to keep your sales history and stats accurate. - Delete: If the item is lost, broken, or never coming back, use
DELETE /items/{id}. - Inactivate: Only use
PUT /items/{id}/inactivateif the item is still available but you want to hide it temporarily (e.g., seasonal products) to make room for others.
- Sold: If the item was sold outside Wallapop, use
Activate: Once you have freed up a slot using one of the methods above, send a
PUT /items/{id}/activaterequest for the target item you wish to publish.
You can include a unique identifier as a query parameter in your webhook URL, for example: https://yourdomain.com/webhook?id=12345. All webhooks notification will be sent to your endpoint with that parameter, allowing you to reliably determine which user the webhook notification belongs to (e.g., by userId, email, or any other unique key in your side).