Skip to main content
A custom Object is an entity in your system — a vehicle, ticket, asset, client — paired with a permanent short scan URL of the form 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 your external_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.
How Objects compare to the other entity types:

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 inserted
  • 200 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.
You can also look up by external_id without writing:

Destinations

Every Object can route scans to one of four destinations. Set destinationType 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}/properties
  • PUT /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.
Properties can also be set inline on POST /objects by including a properties: [...] array on the create payload. The same replace semantics apply.

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-params
  • PUT /objects/{id}/url-params — replace the full set
Live params (whatever the visitor has on 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 on POST /objects, including the external_id upsert. Both arrays are replace-only: send the full desired set every time.
See Scan-specific knowledge for how scan links combine with the chatbot’s.

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.
Sample object.created / object.updated payload (data field):
Sample object.deleted payload:

Next

Object reference

Every field on the Object resource.

Chatbots

The most common scan destination.