diff --git a/docs/guides/ioc-feeds.mdx b/docs/guides/ioc-feeds.mdx
index 26a61d2..5d2f906 100644
--- a/docs/guides/ioc-feeds.mdx
+++ b/docs/guides/ioc-feeds.mdx
@@ -2,47 +2,119 @@
title: "Intelligence Feeds"
---
-import GatedAccessFeatureAddon from '/snippets/gated-access-feature-addon.mdx';
+import GatedAccessFeatureAddon from "/snippets/gated-access-feature-addon.mdx";
Flare exposes Intelligence Feeds delivered via
-[TAXII 2](https://oasis-open.github.io/cti-documentation/taxii/intro.html)
-at `https://api.flare.io/taxii2/`.
+[TAXII 2](https://oasis-open.github.io/cti-documentation/taxii/intro.html). The
+TAXII **discovery** endpoint is `https://api.flare.io/taxii2/`; point your TAXII
+client at it and it will discover the available API roots and feeds below.
## Available Feeds
-| Feed | TAXII 2 ID |
-| ---- | ---------- |
-| Full Feed (with context) | `d6092c37-d8d7-45c3-8aff-c4dc26030608` |
-| IPV4 Only | `feed--689f0191-3b4d-47c8-9313-85820aae7c27` |
-| Domains Only | `feed--a2e7ea2d-ec01-4550-91e5-1316282d01a0` |
-| URLs Only | `feed--af0848cc-ae01-4937-93fe-5d9bf69ba3d2` |
+Flare serves two curated CTI feeds, split by STIX object type:
+
+| Feed | API Root | TAXII 2 Collection ID |
+| ------------ | ------------------------------------------------ | -------------------------------------- |
+| CTI SDO Feed | `https://api.flare.io/taxii2/cti/` | `f1a4ec71-0c00-4f5f-9dbd-e8a4cd33aa66` |
+| CTI SRO Feed | `https://api.flare.io/taxii2/cti/relationships/` | `f1a4e540-2c14-4d5f-8bbc-2e7eb31ad104` |
+
+- The **CTI SDO Feed** delivers STIX Domain Objects (indicators and related
+ Flare-curated cyber threat intelligence).
+- The **CTI SRO Feed** delivers STIX Relationship Objects — the `relationship`
+ objects that link the SDOs together.
Feed URLs can be constructed using:
-- Format: `https://api.flare.io/taxii2/collections//`
+
+- **CTI SDO Feed**
+ - Format: `https://api.flare.io/taxii2/cti/collections//`
+ - Example: `https://api.flare.io/taxii2/cti/collections/f1a4ec71-0c00-4f5f-9dbd-e8a4cd33aa66/`
+- **CTI SRO Feed**
+ - Format: `https://api.flare.io/taxii2/cti/relationships/collections//`
+ - Example: `https://api.flare.io/taxii2/cti/relationships/collections/f1a4e540-2c14-4d5f-8bbc-2e7eb31ad104/`
+
+## Deprecated Feeds
+
+
+ The feeds below are deprecated in favor of the CTI SDO and CTI SRO feeds
+ above. Please migrate existing integrations to the `/taxii2/cti/` API roots.
+
+
+| Feed | TAXII 2 ID |
+| ------------------------ | -------------------------------------------- |
+| Full Feed (with context) | `d6092c37-d8d7-45c3-8aff-c4dc26030608` |
+| IPV4 Only | `feed--689f0191-3b4d-47c8-9313-85820aae7c27` |
+| Domains Only | `feed--a2e7ea2d-ec01-4550-91e5-1316282d01a0` |
+| URLs Only | `feed--af0848cc-ae01-4937-93fe-5d9bf69ba3d2` |
+
+Deprecated feed URLs can be constructed using:
+
+- Format: `https://api.flare.io/taxii2/collections//`
- Example: `https://api.flare.io/taxii2/collections/d6092c37-d8d7-45c3-8aff-c4dc26030608/`
## Authentication
The intelligence feeds use HTTP Basic Auth, which most TAXII clients support:
+
- The username should be set to `api-key`.
- The password should be your Flare API Key.
Obtaining an API key is documented in the
[Authentication Guide ](/concepts/authentication).
-
## Query Parameters
-| Parameter Name | Description | Example |
-| -------------- | ----------- | ------- |
-| added_after | filter the IOCs that were added after the timestamp | `?added_after=2026-02-04T12:05:00.000Z` |
-| limit | restricts the results by the specified amount | `?limit=25` |
+| Parameter Name | Description | Example |
+| -------------- | --------------------------------------------------- | --------------------------------------- |
+| match[type] | filter the SDO by type | `?match[type]=indicator, malware` |
+| added_after | filter the IOCs that were added after the timestamp | `?added_after=2026-02-04T12:05:00.000Z` |
+| limit | restricts the results by the specified amount | `?limit=25` |
+
+### Supported `match[type]` values
+
+The `match[type]` parameter accepts one or more STIX object types (comma-separated,
+e.g. `?match[type]=indicator,malware`). The **CTI SDO Feed** serves the types
+below; the `relationship` type is served exclusively by the **CTI SRO Feed**.
+
+Any value outside this list returns `400 Unsupported match[type]`.
+
+**STIX 2.1 SDO types**
+
+| `match[type]` value | Object |
+| ------------------- | -------------- |
+| `attack-pattern` | Attack Pattern |
+| `campaign` | Campaign |
+| `indicator` | Indicator |
+| `infrastructure` | Infrastructure |
+| `intrusion-set` | Intrusion Set |
+| `location` | Location |
+| `malware` | Malware |
+| `report` | Report |
+| `threat-actor` | Threat Actor |
+| `tool` | Tool |
+| `vulnerability` | Vulnerability |
+
+**Flare-specific extensions**
+
+These are Flare extensions that have no standard STIX SDO counterpart.
+
+| `match[type]` value | Object |
+| ------------------- | -------------------------------------- |
+| `actor` | Threat actor profile tracked by Flare |
+| `chat-channel` | Monitored chat channel (e.g. Telegram) |
+| `forum-thread` | Forum thread from a monitored source |
+
+
+`match[type]=relationship` is **not** valid on the CTI SDO Feed and returns a
+`400`. STIX `relationship` objects are served by the CTI SRO Feed at
+`https://api.flare.io/taxii2/cti/relationships/collections//`.
+
## Code Examples
Code examples for connecting to the feeds can be found in this Github repository:
+
- https://github.com/Flared/ioc-feeds-example
The following example uses `taxii2-client`, which is
@@ -52,6 +124,7 @@ The following example uses `taxii2-client`, which is
import datetime
import os
+from taxii2client.v21 import ApiRoot
from taxii2client.v21 import Server
from taxii2client.v21 import as_pages
@@ -65,7 +138,18 @@ def main() -> None:
print(server.title)
- api_root = server.api_roots[0]
+ # Deprecated use the ApiRoot with /cti or /cti/relationship instead
+ # api_root = ApiRoot(
+ # url="https://api.flare.io/taxii2/",
+ # user="api-key", # Do not change the user.
+ # password=os.environ["FLARE_API_KEY"],
+ # )
+
+ api_root = ApiRoot(
+ url="https://api.flare.io/taxii2/cti/", # Add relationship to fetch SRO
+ user="api-key", # Do not change the user.
+ password=os.environ["FLARE_API_KEY"],
+ )
start_date: datetime.datetime = datetime.datetime.now() - datetime.timedelta(
hours=2