Appearance
Goals
Create, manage, and query conversion goals for your analytics sites. Goals let you track specific user actions and measure conversion rates with optional revenue tracking.
Base URL: https://app.krafter.dev/api/v1/analytics
Goal Object
json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Signup",
"type": "event",
"match_type": "exact",
"match_value": "signup",
"currency": "USD"
}| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (UUID). |
name | string | Display name for the goal. |
type | string | Goal type: pageview, event, or custom. |
match_type | string | How the match value is evaluated: exact, contains, or regex. |
match_value | string | The value to match against (page path, event name, or custom goal name). |
currency | string | null | ISO 4217 currency code for revenue tracking. null if revenue is not tracked. |
Goal Types
| Type | Triggers When | Match Value |
|---|---|---|
pageview | A visitor views a page matching the value | Page path (e.g., /thank-you) |
event | A custom event fires matching the value | Event name (e.g., signup) |
custom | ka.goal() is called with a matching name | Goal name (e.g., purchase) |
Match Types
| Match Type | Behavior | Example |
|---|---|---|
exact | Value must match exactly | /pricing matches only /pricing |
contains | Value must contain the string | signup matches newsletter_signup |
regex | Value must match the regular expression | /blog/\d+ matches /blog/42 |
Create Goal
Create a new conversion goal for a site.
POST /analytics/sites/:key/goalsRequired scope: analytics:write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the goal. |
type | string | Yes | One of: pageview, event, custom. |
match_type | string | Yes | One of: exact, contains, regex. |
match_value | string | Yes | The value to match against. |
currency | string | No | ISO 4217 currency code (e.g., USD, EUR). |
Example: Pageview Goal
Track conversions when visitors reach a thank-you page:
bash
curl -X POST https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/goals \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Thank You Page",
"type": "pageview",
"match_type": "exact",
"match_value": "/thank-you"
}'Example: Event Goal with Revenue
Track purchase events with revenue in USD:
bash
curl -X POST https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/goals \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Purchase",
"type": "custom",
"match_type": "exact",
"match_value": "purchase",
"currency": "USD"
}'Example Response
json
// 201 Created
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Purchase",
"type": "custom",
"match_type": "exact",
"match_value": "purchase",
"currency": "USD"
}
}List Goals
Retrieve all goals for a site.
GET /analytics/sites/:key/goalsRequired scope: analytics:read
Example Request
bash
curl https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/goals \
-H "Authorization: Bearer YOUR_API_TOKEN"Example Response
json
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Purchase",
"type": "custom",
"match_type": "exact",
"match_value": "purchase",
"currency": "USD"
},
{
"id": "661f9511-f39c-52e5-b827-557766551111",
"name": "Newsletter Signup",
"type": "pageview",
"match_type": "exact",
"match_value": "/newsletter/confirmed",
"currency": null
},
{
"id": "772a0622-a40d-63f6-c938-668877662222",
"name": "Contact Form",
"type": "event",
"match_type": "contains",
"match_value": "contact",
"currency": null
}
]
}Update Goal
Update an existing goal.
PATCH /analytics/sites/:key/goals/:idRequired scope: analytics:write
Request Body
All fields are optional. Only include the fields you want to change.
| Field | Type | Description |
|---|---|---|
name | string | New display name. |
type | string | New goal type. |
match_type | string | New match type. |
match_value | string | New match value. |
currency | string | New currency code. |
Example Request
bash
curl -X PATCH https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/goals/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Completed Purchase",
"currency": "EUR"
}'Example Response
json
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Completed Purchase",
"type": "custom",
"match_type": "exact",
"match_value": "purchase",
"currency": "EUR"
}
}Delete Goal
Delete a goal. This does not delete historical conversion data.
DELETE /analytics/sites/:key/goals/:idRequired scope: analytics:write
Example Request
bash
curl -X DELETE https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/goals/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_TOKEN"Example Response
204 No ContentThe response body is empty.
Get Goal Stats
Retrieve conversion statistics for a specific goal.
GET /analytics/sites/:key/goals/:id/statsRequired scope: analytics:read
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
period | string | 7d | Time period. One of: today, 7d, 30d, 12mo, custom. Each named period is inclusive of today and spans exactly the days it names, so 7d is today and the six days before it. An unrecognised value falls back to 7d. |
from | string | -- | Start date. Required when period=custom. |
to | string | -- | End date. Required when period=custom. |
Example Request
bash
curl "https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/goals/550e8400-e29b-41d4-a716-446655440000/stats?period=30d" \
-H "Authorization: Bearer YOUR_API_TOKEN"Example Response
json
{
"data": {
"conversions": 342,
"unique_conversions": 298,
"revenue": 16758.00
}
}| Field | Description |
|---|---|
conversions | Total number of times the goal was triggered. |
unique_conversions | Number of unique visitors who triggered the goal. |
revenue | Total revenue attributed to the goal. null if no currency is set on the goal. |
A goal-stats query that ClickHouse did not answer returns 503 with {"error": "Analytics storage temporarily unavailable"} — not {"data": {}}, which read as a goal nobody had ever converted.
Scopes
| Scope | Endpoints |
|---|---|
analytics:read | GET /analytics/sites/:key/goals, GET /analytics/sites/:key/goals/:id/stats |
analytics:write | POST /analytics/sites/:key/goals, PATCH /analytics/sites/:key/goals/:id, DELETE /analytics/sites/:key/goals/:id |