Skip to main content
Version: Beta

Introduction

The Extraction Rules API provides programmatic access to create, read, update, and archive extraction rules. Extraction rules define how Fullstory captures structured data from your website or app — pulling values from page elements, URLs, and other sources into named properties for analytics.

Authentication

The HTTP API requires an API key that you can generate from the Fullstory app. The API key must have Admin or Architect level permissions for mutation operations. The header value takes the form "Basic {YOUR_API_KEY}".

Security Scheme Type:

apiKey

Header parameter name:

Authorization

Extraction Rules API Overview

Extraction rules pull structured data from page elements, URLs, or static values into named properties for analytics and segmentation. Each rule has a source (where to look), a scope (where to write the result), and one or more mappings (what to extract).

The API is archive-only. ArchiveExtractionRule stops a rule from capturing data but preserves it for audit history; UnarchiveExtractionRule restores it. There is no public delete RPC — permanent deletion is intentionally UI-only.

Concepts

Source — where the data comes from

A rule has exactly one source:

  • element (ElementSource) — matches page elements by selector. Each selector targets one or more platform values (PLATFORM_WEB, PLATFORM_IOS, PLATFORM_ANDROID) and carries a platform-specific selector string: a CSS selector for web, the view class name for iOS, or the fragment class name for Android. Multiple selectors in one rule combine with OR semantics.
  • url (UrlSource) — matches the page URL. Set any: true to consider every URL; per-mapping URL component selection happens in UrlValue (see below).

Scope — where the data goes

A rule has exactly one scope, applied to all of its mappings:

  • SCOPE_PAGE — writes to a page-scoped property (page name or a custom page property).
  • SCOPE_USER — writes to a user-scoped property (uid, email, display name, or a custom user property).
  • SCOPE_ELEMENT — writes to an element-scoped property.

Mapping — what to extract and where to write it

Each mapping has three parts:

  • value source — exactly one of element_value, url_value, or static_value.
    • element_value reads from the matched element. Use attribute to read an HTML attribute by name, or set inner_text: true to read the element's text content.
    • url_value reads a piece of the URL. Set one of the boolean flags full, path, host, or fragment to true, or set the string field query to the parameter name (for example "utm_campaign").
    • static_value writes a fixed string regardless of page content.
  • target — exactly one of the built-in Fullstory properties (api_name, uid, email, display_name) or a custom Property identified by name and data_type.
  • operation (optional) — a ValueProducer transform applied to the raw value before it is written. Today the only supported transform is a regex (regex.expression, with an optional regex.format string referencing capture groups like $1).

Active rule limits

Each org has a per-scope active_limit. Archiving a rule frees a slot; unarchiving consumes one. ListExtractionRules.usage_by_scope reports active_limit and active_count for each scope so callers can detect when an org is at the limit before attempting to create or unarchive.

Optimistic concurrency (etag)

Every rule has an opaque etag set by the server on read. Pass it on UpdateExtractionRule (PATCH) or Replace Extraction Rule (PUT). If the rule has changed since you read it, the server returns HTTP 409 Conflict — re-fetch, reconcile, and retry.

Updating rules: PATCH vs PUT

Two update endpoints sit on the same resource path:

  • PATCH /v2beta/extraction/rules/{id} (UpdateExtractionRule) — partial update. Send only the fields you want to change; the rest stay as they are.
  • PUT /v2beta/extraction/rules/{id} (Replace Extraction Rule) — whole-resource replace. Send the complete rule body; every editable field is overwritten and unset fields are cleared.

Both honour the same etag flow. Choose PUT when you already hold the full intended rule state (for example, after editing it in your own UI). Choose PATCH when you only know the deltas.

PUT is friendly to a Get → mutate → PUT round-trip: server-managed fields on the rule body (created_at, updated_at, etag, archived) are silently ignored on input, so you can echo a Get response straight back without stripping fields. The body's id, if set, must agree with the id in the path.

Archive vs delete

This API is archive-only. ArchiveExtractionRule stops a rule from capturing data but preserves it for historical context. UnarchiveExtractionRule restores it (subject to active_limit). Permanent deletion is UI-only.

Unrepresented rules

Some legacy rules in an org cannot be modeled by the public API surface today. They count toward active_count but do not appear in List results. The unrepresented_count field on each scope of usage_by_scope reports how many such rules are present on the current page. Manage those rules from the Fullstory UI.

Worked Example: Capture product price from a cart element

This rule watches the cart summary on the web app, reads the data-price attribute off the matched element, strips the leading currency symbol with a regex, and writes the result into a custom page-scoped property product_price of type DATA_TYPE_FLOAT.

{
"rule": {
"name": "Capture Product Price",
"description": "Extracts the product price from the cart summary element",
"scope": "SCOPE_PAGE",
"source": {
"element": {
"selectors": [
{
"platform": ["PLATFORM_WEB"],
"selector": "#cart-summary .price"
}
]
}
},
"mappings": [
{
"element_value": {
"attribute": {
"attribute": "data-price"
}
},
"target": {
"custom": {
"name": "product_price",
"data_type": "DATA_TYPE_FLOAT"
}
},
"operation": {
"regex": {
"expression": "^(\\d+\\.\\d{2})"
}
}
}
]
}
}

Worked Example: Capture campaign from URL query parameter

This rule reads the utm_campaign query parameter from any page URL and writes it into a custom user-scoped property acquisition_campaign of type DATA_TYPE_STRING.

{
"rule": {
"name": "Capture utm_campaign",
"description": "Reads the utm_campaign query parameter into a user property",
"scope": "SCOPE_USER",
"source": {
"url": {
"any": true
}
},
"mappings": [
{
"url_value": {
"query": "utm_campaign"
},
"target": {
"custom": {
"name": "acquisition_campaign",
"data_type": "DATA_TYPE_STRING"
}
}
}
]
}
}