resellflip Guides

Developers · published on

The resellflip API

You send the name and condition of an item. The API sends back a resale price, its range, and the number of completed sales found for that item. Two endpoints, prepaid credits, no subscription.

Your first call in two minutes

1. Create a key

Sign in (or create an account), open the developer space and click “Create a key”. Copy it right away: it is shown only once. Your first key comes with 1,000 free credits, i.e. 100 estimates, no card needed. The app is in French for now.

2. Paste this call into a terminal

Replace the key on the first line with yours. The rest works as is.

export RESELLFLIP_API_KEY="rf_live_paste_your_key_here"

curl https://resellflip.com/api/v1/estimate \
  -H "Authorization: Bearer $RESELLFLIP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Doudoune Uniqlo", "condition": "Bon", "size": "M"}'

3. Read the response

{
  "price": 35,
  "price_low": 28,
  "price_high": 42,
  "confidence": "moyenne",
  "category": "Mode",
  "comps_count": 0,
  "sales_count": 0,
  "rotation_days": null,
  "rotation_samples": null,
  "credits_remaining": 990
}

The values above are an example. Look at comps_count first: the number of comparable items found in the corpus. sales_count says how many of them are completed sales; at 0, no sale weighed on the price. Our corpus is young: today both are often 0, and the price is then estimated without comparables. confidence is the model’s view of the item, not of the corpus: test these two counters. The call cost you 10 credits; your balance is in credits_remaining.

Call the API from your server. In a browser or an app installed on your users’ devices, anyone could read the key.

Response fields

Field What it holds
price The suggested resale price
price_low, price_high The range. A fair price is an interval.
confidence haute, moyenne or basse (high, medium, low). The model’s view of the item, not of how many sales back it.
category The detected category
comps_count The number of comparable items found: completed sales, or failing that, estimates of items still in stock. Can be 0.
sales_count The completed sales found. At 0, no sale weighed on the price, even when comps_count is positive.
rotation_days The median time from stocking to selling, in days. null until there are five sales from three distinct sellers: we would rather say nothing than make up a delay.
rotation_samples The number of sales behind that delay
credits_remaining Your balance after the call

For an item the corpus knows well, the response looks more like this: seven sales behind the price, and a resale delay.

{
  "price": 50,
  "price_low": 40,
  "price_high": 60,
  "confidence": "haute",
  "category": "Mode",
  "comps_count": 7,
  "sales_count": 7,
  "rotation_days": 21,
  "rotation_samples": 7,
  "credits_remaining": 90
}

The corpus is filtered before use: the last eighteen months, one row per seller, and never a figure built on a single seller.

Within version 1, we may add fields, never remove or rename them. Ignore the ones you do not know and your code will not break.

The two endpoints

Both take a POST, a JSON body, and your key in the Authorization: Bearer header. No SDK, no webhooks, no sandbox: the trial runs on the real corpus.

POST /api/v1/estimate · 10 credits

A full estimate. The JSON body:

Field Type Required Constraint
name string yes, unless images 200 characters; the brand is inferred from it
condition string yes one value from the list below
size string no 30 characters
notes string no 500 characters: flaws, details
images array of objects yes, unless name 3 at most, format below
gradingService string no PSA, BGS, CGC or SFG
gradingGrade number yes if gradingService 1 to 10, in half points

Text that is too long is truncated, not rejected. There is no brand field on this endpoint.

condition only takes these values, written exactly as shown, accents and capital included. They are the French values the app uses. Clothing and goods: Neuf, Très bon, Bon or Satisfaisant. Trading cards (Cardmarket scale): Mint, Near Mint, Excellent, Good, Light Played, Played or Poor. “Very good” or “neuf” return a 400, and nothing is charged.

images: up to 3 { "mime_type", "data" } objects. data is the image in base64, without a data: prefix. Accepted types: image/jpeg, image/png or image/webp. Each data is at most 2,800,000 characters, about 2 MB decoded. One invalid image and the whole call returns a 400, and nothing is charged.

{
  "condition": "Bon",
  "images": [
    { "mime_type": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQ…" }
  ]
}

POST /api/v1/comps · 1 credit, 0 if the list is empty

The raw comparable items, without an estimate, five at most. Each row carries kind: sale for a completed sale, estimate for an item still in stock. For a sale, net_price is the net seller price: what the seller received, platform fees deducted. For an estimate, it is the price its owner is aiming for.

The body carries name, required (200 characters), and brand, optional (80 characters). Without brand, the brand is inferred from the name. No photos on this endpoint: to recognise an item from an image, use /estimate. Add "sold_only": true to get sales only; it defaults to false. comps_count and sales_count mean the same as on /estimate, and can exceed five.

curl https://resellflip.com/api/v1/comps \
  -H "Authorization: Bearer $RESELLFLIP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Doudoune Uniqlo", "brand": "Uniqlo"}'

Example response:

{
  "comps": [
    {
      "name": "Doudoune Uniqlo",
      "brand": "Uniqlo",
      "condition": "Bon",
      "size": "M",
      "net_price": 32.5,
      "days_ago": 12,
      "kind": "sale"
    },
    {
      "name": "Doudoune ultra légère Uniqlo",
      "brand": "Uniqlo",
      "condition": "Très bon",
      "size": "L",
      "net_price": 40,
      "days_ago": 5,
      "kind": "estimate"
    }
  ],
  "comps_count": 9,
  "sales_count": 9,
  "rotation_days": 18,
  "rotation_samples": 9,
  "credits_remaining": 90
}

Today you will often get an empty list. It is a 200, and nothing is charged:

{
  "comps": [],
  "comps_count": 0,
  "sales_count": 0,
  "rotation_days": null,
  "rotation_samples": null,
  "credits_remaining": 1000
}

If the corpus takes more than 2.5 seconds to answer, you also get this empty list. So you cannot tell “no items” from a slow database. Either way, nothing is charged.

Errors

Every error carries a stable code and a readable error message. Test the code: the message may change.

Status code Meaning Charged?
400 invalid_request Invalid body: missing field, condition not in the list, image rejected No
401 unauthorized Key missing, unknown or revoked No
402 insufficient_credits Balance too low for this call No
403 account_suspended API access suspended for this account: none of its keys work No
404 — Endpoint not part of version 1 No
405 — Method other than POST No
429 rate_limited More than 60 calls per minute for this key No
500 internal_error Internal error Refunded
502 upstream_error The estimation service did not answer Refunded
503 unavailable Service unavailable No
504 upstream_error The estimate took too long. Try again. Refunded

A 429 rate_limited carries a Retry-After header, in seconds. A 429 upstream_error, rarer, means our estimation service is saturated: the call is refunded. The 401 returns the same message for a missing key and an unknown one, on purpose. “Refunded” means the credits are taken at the start of the call and given back straight away: your balance does not move.

Pricing

Prepaid credits, paid once, no subscription. An estimate costs 10 credits. A call to /comps costs 1, and nothing when it finds nothing.

Plan Credits Estimates Price Per estimate
Trial 1,000 100 Free Once per account
Pack S 10,000 1,000 €49 €0.049
Pack M 100,000 10,000 €390 €0.039 (−20%)
Pack L 1,000,000 100,000 €2,900 €0.029 (−40%)
Beyond — — On quote —

Credits do not expire in the current version of the offer. Unused credits from a pack are refundable on request. An error on our side (5xx) costs you nothing. Charged in euros. The publisher is exempt from VAT under article 293 B of the French tax code (CGI): the price shown is the price paid.

Beyond pack L, write to contact@resellflip.com. Send us your categories too: we will tell you what the corpus really covers for you.

Frequently asked questions

What happens when the corpus does not know the item?

You still get a price, but without any comparable item: comps_count and sales_count are 0. The corpus is young, so this happens often. Read that field before showing the price to your users.

Am I charged for a failed call?

No. An error on your side (400, 401, 402, 429) charges nothing. An error on ours (500, 502, 504) is refunded straight away. An outage (503) is not charged.

Do credits expire?

No, not in the current version of the offer. Unused credits from a purchased pack are refundable on request. Trial credits are not.

Can I store the comparable items returned?

You can show them to your users and keep them for as long as it takes to serve them. You cannot pile them up to rebuild the corpus, resell them as a database, query the API in a loop to harvest it, or use it to build a competing estimation service. The terms of use spell this out.

What if my key has leaked?

Revoke it and create a new one. We only keep its fingerprint, so we cannot send it back to you. Every call signed with it draws on your credits: never put it in code that runs on your users’ devices.

Terms

Use of the API is governed by the “API for professionals” section of the terms of use: prepaid credits, acceptable use, key security, revocation in case of abuse. The terms are written under French law, and only the French version is binding. No seller’s personal data leaves through the API: a comparable item is an item name, a brand, a condition, a size, a price, an age and its nature (kind): sale or estimate.

Three uses are prohibited: using the API to offer a competing resale price estimation service, harvesting or reselling the corpus (by querying /comps in a loop, for example), and getting around the limits with several accounts or keys. If that happens, every key on the account is suspended on the spot and answers 403 account_suspended. Credits used that way are not refunded. Unused credits from a purchased pack stay refundable as usual, less the credits used in breach.

Already have an account? Sign in, then open the developer space.

Create my key

Read next: How we calculate · App pricing