Welcome to the Uptick API documentation! Our API empowers publishers to seamlessly integrate our ad platform into their offer flow, enabling them to provide targeted offers to their users at crucial moments during the checkout process or while waiting for order delivery. By leveraging our API, publishers can enhance user experience and maximize revenue opportunities.
There are 3 main operations when working with our API.
This endpoint allows publishers to create a new offer flow for end users, defining the parameters and triggers for displaying relevant offers.
Publishers can use this endpoint to request offers for a specific offer flow, triggering the retrieval of targeted offers from our platform.
This is to send an event back to the server, specifically for the offer_viewed event.
You always start by creating a new flow and then following the links in the response.
graph LR A[New Offer Flow] -- Links --> B((Next Offer)) B[Next Offer] -- Links --> C((Flow Event))
/api/v1/flows/new
links section, find and use the url for next_offer
next_offer will have a links section, find and use the url for offer_event and append ev=offer_viewed.
Explore the detailed documentation for each endpoint to understand how to make requests, handle responses, and integrate our API seamlessly into your offer flow. If you have any questions or need assistance, our support team is here to help.
Status: stable · Applies to: component_template_* offer templates
This is the platform-independent contract for how a segment tree renders. Every implementation — the web renderer (Ruby + Tailwind, in this pack) and the future mobile SDK (consuming the same API payload) — MUST produce these exact values. If a token resolves to a different size or color in any implementation, that implementation is wrong, not this document.
This is the value contract: the concrete sizes, colors, borders, and layout rules every renderer must reproduce, plus (§11) which styles each segment type accepts. How the web renderer is built internally — style groups, the dev-mode validator, Tailwind specifics — is documented alongside its source and is not needed to consume this contract. For the exact attributes each segment type accepts, with descriptions, see that type’s API endpoint.
Versioning. Frozen at 1.0. Any change to a value or token is a new version (1.1, 2.0). A payload does not carry a spec version; the placement’s template family fixes it.
The web renderer expresses spacing and sizing in em (relative to the
element’s own font-size), not rem/px. The canonical value is the em.
Everything keys off one absolute base font-size. Because the scale is
em-based, the offer’s base font-size scales the entire design — text and
spacing and box sizes — proportionally. The base is set once, as an
absolute px value on the offer root (not an em/rem token), so the offer
renders at the same size on every host site regardless of the host page’s
font-size. It is a per-template input:
component_template_100 anchors its base to a fixed 14px (matching
template_002). So its concrete px = em × 14, exactly, on any site.
base / 16 for a given template (e.g. ×14/16 for ct100, so
medium = 14px, large = 15.75px, x-large = 17.5px, …).
An implementation conforms by reproducing the em ratios against the template’s declared absolute base, not the 16px reference numbers literally.
padding, margin_*
Contiguous; each step is +0.25em. No skipped steps. Extend with higher numbered
labels (4x-loose …) rather than gaps.
| token | em | px@16 |
|---|---|---|
x-tight |
0.25 | 4 |
tight |
0.5 | 8 |
normal |
0.75 | 12 |
loose |
1.0 | 16 |
x-loose |
1.25 | 20 |
2x-loose |
1.5 | 24 |
3x-loose |
1.75 | 28 |
padding: a single token (all sides), [vertical, horizontal], or
[top, right, bottom, left]. none (or an absent side) = 0.
margin_top / margin_right / margin_bottom / margin_left: a single
token, optionally negated with a leading - (e.g. -tight = -0.5em / -8px).
Negative applies to margins only (there is no negative padding/size/border).
width, height, badge size
One shared, contiguous scale (+0.25em per step). width: small == height: small
== a badge’s size: small.
| token | em | px@16 |
|---|---|---|
2x-small |
0.75 | 12 |
x-small |
1.0 | 16 |
small |
1.25 | 20 |
medium |
1.5 | 24 |
large |
1.75 | 28 |
x-large |
2.0 | 32 |
2x-large |
2.25 | 36 |
width / height also accept auto and full (100% of the parent).
size drives both the circle dimensions (this scale) and its
font (the font scale below) from the one token.
size
| token | em | px@16 |
|---|---|---|
2x-small |
0.625 | 10 |
x-small |
0.75 | 12 |
small |
0.875 | 14 |
medium |
1.0 | 16 |
large |
1.125 | 18 |
x-large |
1.25 | 20 |
2x-large |
1.5 | 24 |
3x-large |
1.875 | 30 |
4x-large |
2.25 | 36 |
extraSmall is a legacy alias for x-small (rich-text-parser output).
size is em, so it compounds when nested. A sized element inside another
sized element multiplies — e.g. a large (1.125em) text run inside an
x-large (1.25em) heading renders at 1.25 × 1.125 × base, not 1.25 × base. Each
piece of text must be sized once: a heading owns its size and its text runs
inherit it (don’t carry their own size). An implementation that applies
absolute per-element sizes (no cascade) must therefore flatten to one size per
text run to match.
Named tokens resolve to fixed hex. Any non-named value (a #hex or rgb(...))
passes through verbatim as an inline color.
| token | hex |
|---|---|
white |
#FFFFFF |
lightergray |
#E5E7EB |
lightgray |
#9CA3AF |
gray |
#6B7280 |
darkgray |
#374151 |
black |
#000000 |
A token resolves to the same hex whether used as text, background, or border
color. (lightergray is the light fill; lightgray is the mid-tone used for
secondary text.)
appearance: subdued = muted secondary treatment (decoration color
#E5E7EB); monochrome = text color #E5E7EB.
| attribute | values |
|---|---|
border (line style) |
none, solid, dashed, dotted |
border_width |
none=0, small=1px, medium=2px, large=4px — or a per-side array (same shape as padding). Native 1/2/4 scale; no 3px step. |
border_color |
the color tokens in §5 (default mid-gray #888888 when border is set without a color) |
border_radius |
rounded = 4px, full = fully rounded (pill/circle) |
Border style, width, and color are independent axes. Widths are absolute
px (not em-scaled).
max_width |
em | px@16 | max_height |
em | px@16 | |
|---|---|---|---|---|---|---|
small |
7 | 112 | 2x-small |
1.75 | 28 | |
medium |
9 | 144 | x-small |
3.5 | 56 | |
large |
11 | 176 | small |
7 | 112 | |
medium |
9 | 144 | ||||
large |
11 | 176 |
| attribute | values → behaviour |
|---|---|
display |
none (hidden), auto (flex), block, inline_block |
direction |
horizontal (row), vertical (column) |
align |
main-axis justify + cross-axis center: start, center, space-between, end |
vertical_align |
align-self: start, center |
order |
integer flex order |
columns (on a flex parent) |
per-child array; each entry sizes that child: auto (grow+shrink to content), fill (equal share), none (fixed), 25% / 50% / 75% (basis fraction) |
desktop_attributes
A single breakpoint. desktop_attributes holds overrides applied at
viewport width ≥ 768px; below that, base attributes apply. Any attribute
may be overridden. (Web implements this with Tailwind’s md:; the mobile SDK
applies the override above its own 768px-equivalent threshold.)
Implemented overrides today: display, direction, align, columns,
width, height, size, padding.
Bespoke container: full-viewport overlay (#000000 at 40% opacity) with 6em
top padding, and a centred white panel (≈92% width on mobile, 80% on desktop)
with a drop shadow and slide-down entry. Panel max width by max_width:
narrow = 400px, wide = 1000px, default = 800px.
Styling attributes are partitioned into groups; each segment type accepts a fixed set of them. A renderer MUST ignore (and SHOULD warn on) an attribute applied to a type that does not support its group.
| Group | Attributes |
|---|---|
| base (always on) | display |
| typography | color, size, text_align, underline, appearance |
| text_inline | emphasis, white_space |
| box | padding, margin_top / margin_right / margin_bottom / margin_left, background, border, border_width, border_color, border_radius |
| flex_container | direction, align, columns |
| flex_item | order, vertical_align |
| sizing | width, height, max_width, max_height |
| Type | base | typography | text_inline | box | flex_container | flex_item | sizing |
|---|---|---|---|---|---|---|---|
view |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
grid |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
inline_layout |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
block_layout |
✓ | ✓ | ✓ | ✓ | ✓ | ||
text |
✓ | ✓ | ✓ | ||||
heading |
✓ | ✓ | |||||
button |
✓ | ✓ | ✓ | ✓ | ✓ | ||
link |
✓ | ✓ | ✓ | ✓ | ✓ | ||
pressable |
✓ | ✓ | ✓ | ✓ | ✓ | ||
image |
✓ | ✓ | ✓ | ✓ | ✓ | ||
badge |
✓ | ✓ | ✓ | ||||
spacer |
✓ | ✓ | ✓ | ✓ | |||
modal |
✓ | ||||||
icon / newline / default |
✓ |
Notes:
- block_layout has a fixed internal layout, so it omits flexcontainer (an
align/direction would fight its baseline); it still accepts flexitem.
- Text types take no box/flex/sizing — spacing around copy belongs on a
wrapping container, not the text run itself.
- columns is authored on a flex parent (grid / inline_layout) to size its
children; icon / newline / default render fixed markup and ignore
attributes.
For the exact attributes each type accepts, with descriptions and allowed values, see that type’s API endpoint.
Two renderers conform to v1.0 when, for an identical segment payload, every
resolved value (spacing, size, font, color, border, radius, layout, and the
≥768px overrides) matches the tables above. The web renderer’s golden-master
test (segment_golden_master_test.rb) locks its output; the mobile SDK should
carry an equivalent fixture suite checked against these same values.
| Resource | Description |
|---|---|
| POST /v1/places/:integration_id/flows/:flow_id/events | Flow Event |
| Resource | Description |
|---|---|
| POST /v1/places/:integration_id/flows/:flow_id/feedbacks | Offer Feedback |
| Resource | Description |
|---|---|
| GET /v1/places/:integration_id/flows/new | New Offer Flow |
| GET /v1/places/:integration_id/flows/:id | Show Offer Flow |
| Resource | Description |
|---|---|
| HEAD /v1/items/flow | Flow |
| HEAD /v1/items/event | Event |
| Resource | Description |
|---|---|
| GET /v1/places/:integration_id/flows/:flow_id/offers/new | Next Offer |
| GET /v1/places/:integration_id/flows/:flow_id/offers/:id | Show Offer |
| Resource | Description |
|---|---|
| HEAD /v1/segments/modal | Modal |
| HEAD /v1/segments/view | View |
| HEAD /v1/segments/block_layout | Block Layout |
| HEAD /v1/segments/inline_layout | Inline Layout |
| HEAD /v1/segments/grid | Grid |
| HEAD /v1/segments/newline | Newline |
| HEAD /v1/segments/text | Text |
| HEAD /v1/segments/image | Image |
| HEAD /v1/segments/heading | Heading |
| HEAD /v1/segments/link | Link |
| HEAD /v1/segments/button | Button |
| HEAD /v1/segments/icon | Icon |
| HEAD /v1/segments/badge | Badge |
| HEAD /v1/segments/spacer | Spacer |
| HEAD /v1/segments/pressable | Pressable |