https://award.ee/o/{public_slug}. You decide what type means, what goes in metadata, and where scans route to.
When to reach for Objects
Objects are for any custom entity in your system that needs a permanent scan URL on top of it — typed by you, indexed by yourexternal_id. The shape is intentionally generic so you can model whatever doesn’t fit a built-in resource.
Typical examples:
- Customer records / Clients — CRM contacts, accounts, leads.
- Receipts / Invoices — issued documents, statements.
- Vehicles, assets, equipment — fleet, tooling, serialised inventory.
- Tickets, work orders — support cases, repair jobs, service tasks.
- Anything custom — a row in your domain that needs a scan handle.
Objects
Anything else. You bring the
type and external_id; we mint and own the
slug. Built for integrations.Products
Physical SKU-keyed catalog items, indexed by GTIN. For retail goods with
barcodes. See Products.
QR Codes
Printed-first generic short URLs. Created in the dashboard and shipped on
stickers. See QR Codes.
Idempotency by external_id
external_id is your identifier. Pass it on POST /objects and the call is idempotent on the pair (org_id, external_id). Replaying the same external_id never creates a duplicate row — it updates the existing one with whatever you sent and returns the same id and public_slug.
The status code tells you what happened:
201 Created— new row inserted200 OK— existing row was updated
Objects without an
external_id aren’t deduplicated — every POST creates a
fresh row. Always pass an external_id from CRM/upstream syncs.Destinations
Every Object can route scans to one of four destinations. SetdestinationType and the matching target ID/URL on create or update.
When
destinationType is null, the scan URL serves a default landing page.
Properties
properties are typed key/value pairs attached to an Object. They power variable substitution inside chatbot prompts and pages ({{object.<type>.<key>}}) and show up in the dashboard as structured fields.
Properties live at their own sub-resource:
GET /objects/{id}/propertiesPUT /objects/{id}/properties— replace the full set
PUT is replace-only. Pass every property you want to keep; anything omitted gets removed. Keys are unique per object — you can’t ship the same key twice in a request.
URL params
url_params are static query-string params merged into the scan-redirect URL. Use them to pass tracking, source attribution, or any static context downstream.
GET /objects/{id}/url-paramsPUT /objects/{id}/url-params— replace the full set
award.ee/o/<slug>?...) win on key collision.
The scan-redirect flow
1
Visitor scans
Visitor hits
https://award.ee/o/{public_slug}. The slug is generated when
the Object is created and never changes.2
We resolve
We look up the Object, merge
url_params (static) with the live query
string (live wins), and emit an object.scanned webhook.3
We redirect
Routed by
destinationType: chatbot URL, page render, KB index, or external
URL. If no destination is set, the default landing page is served.Scans are never directly creatable through the API — they happen when someone
actually loads the scan URL. To get notified, subscribe to the
object.scanned webhook (see below).Deletion
DELETE /objects/{id} removes the object. Future scans of its slug 404, and subsequent reads of the id return 404 not_found. Slugs are never reused — a deleted object’s public_slug will not be reassigned to a new object, even if you upsert a fresh row with the same external_id.
Attach knowledge
Link the articles and folders that are specific to this object. Visitors who scan it get them on top of the chatbot’s own knowledge, so a question like “how do I turn the TV on?” is answered from this object’s manual, not a guess across every one. You can also send them onPOST /objects, including the external_id upsert. Both arrays are replace-only: send the full desired set every time.
Webhook events
Four events fire over an Object’s lifecycle. Payloads ship inside the standard event envelope — see Webhooks overview.event
New Object row inserted. Fires once per
(org_id, external_id).event
Any field on the row changed — including upsert replays that touched columns.
event
Someone loaded
award.ee/o/{public_slug}. Use this to drive real-time
notifications.event
Object was deleted. Slug stays reserved and won’t be reassigned.
object.created / object.updated payload (data field):
object.deleted payload:
Next
Object reference
Every field on the Object resource.
Chatbots
The most common scan destination.

