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:
| Answer | Costs 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 side | No |
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.
| Ceiling | Limit | Counted per | Window |
|---|---|---|---|
| Card requests | 600 | your business | a sliding minute |
| Card requests | 50,000 | your business | a sliding 24 hours |
whoami and capabilities together | 60 | your business | a sliding minute |
| Failed key attempts | 30 | network address | a sliding minute |
| Requests carrying one key | 1,200 | that key | a 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:
| Header | Meaning |
|---|---|
Retry-After | Seconds to wait before trying again. |
X-RateLimit-Limit | The ceiling you reached. |
X-RateLimit-Remaining | What is left in the window. |
X-RateLimit-Reset | When 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:
| Situation | What to do |
|---|---|
| Your copy is less than 24 hours old | Serve it. Do not ask us. |
| Your copy is 24 hours old or more, or you have none | Ask us for the card, store it, serve it. |
We answer in_review or not_found | Drop 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 all | Keep 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 count | Meaning |
|---|---|
calls | Cards served today. Each one used a call from your allowance. |
public_hits | Cards served today, counted as they were handed over. Normally the same as calls. |
in_review | Answers for perfumes held back while checked. |
not_found | Answers for ids we do not hold. |
refused | Requests 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.