Skip to main content

Limits and caching

What costs a call​

Only a card we serve. A 200 answer with status: "public" uses one call from your monthly allowance. Nothing else does:

AnswerCosts a call?
A card (status: "public")Yes, one
An unchanged card, re-checked with If-None-Match (304)No
Held back while checked (in_review)No
No such perfume (not_found)No
Not a fragrance id (invalid_id)No
Checking your key or what you can use (whoami, capabilities)No
A refusal of your key, a ceiling reached, or a fault on our sideNo

We check the id and read the card before anything is taken from your allowance, so a typo, a perfume held back, or a failure on our side never costs you a call.

Your monthly allowance​

Each business has a monthly allowance of cards, set when we set up your business record. capabilities shows it, with how much you have used. The allowance belongs to your business, not to a key and not to a server: every key and every server you run share it, and a new key does not reset it.

When it is used up, card requests answer 429 with the code over_allowance until the month turns over. The count runs on UTC dates, so it starts again at 00:00 UTC on the first day of the month, which is 10 or 11 in the morning in Sydney depending on daylight saving. Keep serving your stored copies in the meantime (below).

The ceilings​

These stop a runaway loop, not normal use.

CeilingLimitCounted perWindow
Card requests600your businessa sliding minute
Card requests50,000your businessa sliding 24 hours
whoami and capabilities together60your businessa sliding minute
Failed key attempts30network addressa sliding minute
Requests carrying one key1,200that keya sliding minute

The card ceilings count every card request with a valid key, served or not, and your whole fleet of servers shares them.

The 24-hour ceiling is a sliding window, not a calendar day. It frees up as the requests from 24 hours earlier fall out of it. There is no daily reset at midnight in any time zone.

Failed key attempts are counted per network address, and only when the key failed: no key at all (no_key), or a key that is not one of ours (unknown_key). They are checked before we look a key up, so a wrong key cannot make us do database work. A request with a valid key never counts toward it, so your servers are held only to your business's ceilings even when they share one address. But a single server with a mistyped key can use up its address's 30 attempts, and then every request from that address waits up to a minute, so fix a key the moment unknown_key appears.

The per-key ceiling sits above anything your business's own ceilings let you reach, so you only meet it if a copy of your key is being used somewhere else. If you do, rotate the key.

These are first numbers, set before anyone was using the door. If they are wrong for you, say so.

When you reach a ceiling​

You get 429 with the code rate_limited, and these headers:

HeaderMeaning
Retry-AfterSeconds to wait before trying again.
X-RateLimit-LimitThe ceiling you reached.
X-RateLimit-RemainingWhat is left in the window.
X-RateLimit-ResetWhen the window resets, in milliseconds since 1 January 1970 (UTC).

Wait for Retry-After, then carry on. Do not retry in a tight loop: every retry is another request against the same ceiling.

Keeping a stored copy​

This is the one rule for how long you may keep and serve a card. Every page in these docs, and the worked examples, follow it.

Store each card in your own database, keyed by the Sniffopotamus id, with the time you fetched it. Then:

SituationWhat to do
Your copy is less than 24 hours oldServe it. Do not ask us.
Your copy is 24 hours old or more, or you have noneAsk us for the card, store it, serve it.
We answer in_review or not_foundDrop your copy at once and show your page without the card.
We answer with any other error (401, 403, 429, 500, 503), including a used-up month, or do not answer at allKeep serving your copy if it is less than 7 days old; otherwise show your page without the card. Try again later.

In short: 24 hours fresh, up to 7 days when we error or your allowance is out, dropped at once on in_review or not_found. A copy is never served once it is 7 days old.

Only one of your servers needs to refresh a given card at a time. If fifty shoppers open the same listing at once, one refresh is enough.

With this rule each perfume you show costs at most about one call a day, and a shopper never waits on us while your copy is fresh.

Never keep serving a card we answered in_review or not_found for. A perfume is usually held back because something in it was found to be wrong.

The HTTP headers​

A card answer carries a Cache-Control header marked private, so a shared cache between your server and ours never hands one business's answer to another. That header is for web caches in the path. It is not the rule for your stored copy; the rule above is. Every other answer carries Cache-Control: no-store.

A card answer carries an ETag. When you ask for the same card again, send it back as If-None-Match. If the card has not changed we answer 304 Not Modified with no body, and a 304 costs no call. If it has changed, you get the new card with a new ETag, and that one costs a call as usual. A 304 still needs a valid key and still counts against your per-minute and 24-hour card ceilings. Keep the ETag beside your stored copy, and use it when the copy is 24 hours old.

We cache nothing on our side. A correction reaches the very next request.

When cards change​

Cards change when our catalogue team publishes a checked correction. With the rule above, a correction reaches your page the next time your copy is refreshed, within 24 hours. Change alerts, which will tell your server sooner, are planned.

Reading your own usage​

GET /api/partner/v1/whoami is free and answers with today's counts for your business (today in UTC). capabilities adds this month's use, your allowance and when the count starts again.

Today's countMeaning
callsCards served today. Each one used a call from your allowance.
public_hitsCards served today, counted as they were handed over. Normally the same as calls.
in_reviewAnswers for perfumes held back while checked.
not_foundAnswers for ids we do not hold.
refusedRequests with something that is not a fragrance id.

Refusals of your key and ceilings reached are not in these counts yet. If card reads are not switched on for accounts yet, the counts can stay at 0 whatever you send; capabilities says whether they are. Put whoami in your health check rather than spending a card to see whether you are connected.

Back to SniffopotamusReturn to the app