Tier: Free, no studio key requried.
How the flow works
- A logged-in buyer generates a code for a product they own. It looks like
HFP-QCN-VJ7. - The buyer pastes the code wherever verification is needed (e.g. a
/verifyDiscord command). - Your integration calls the public check endpoint with the code.
- You get back a verdict plus the product it proves ownership of, and nothing about the buyer.
- Short-lived, valid for 10 minutes.
- Single-use, the first successful check consumes the code; anyone replaying it gets
already_used. Only one checker can ever receivevalid: true. - Privacy-preserving, the check response never contains the buyer’s identity, so no user data changes hands.
Generating a code (buyer side)
The easiest way: send buyers to the verification page on the store,POST /api/purchases/verify/{productId} with a logged-in NMCrate session. productId accepts the product slug or id.
403 with code: "NOT_OWNED".
Checking a code (integrator side)
GET /api/purchases/verify/check/{token}, public, no authentication; the code itself is the proof.
hfpqcnvj7 works). The response is always HTTP 200, the verdict is in the body:
valid | reason | Meaning |
|---|---|---|
true | , | The code proves ownership of product. It is now consumed. |
false | invalid_format | The input can’t be a code (must be 9 characters, A–Z / 2–9). |
false | not_found | No such code, mistyped, or expired long enough ago to be purged. |
false | expired | The code existed but its 10 minutes are up. |
false | already_used | The code was already checked once. Treat with suspicion, someone may be replaying a code they saw elsewhere. |
Always compare the returned
product.id (or slug) against the product you are verifying for. A valid code proves ownership of the product it was generated for, not of your product specifically.