Ingest STIX threat intelligence

Note: This endpoint is in preview and is subject to change. If you have any feedback, contact Datadog support.

POST https://api.ap1.datadoghq.com/api/v2/security/threat-intel/stixhttps://api.ap2.datadoghq.com/api/v2/security/threat-intel/stixhttps://api.datadoghq.eu/api/v2/security/threat-intel/stixhttps://api.ddog-gov.com/api/v2/security/threat-intel/stixhttps://api.us2.ddog-gov.com/api/v2/security/threat-intel/stixhttps://api.uk1.datadoghq.com/api/v2/security/threat-intel/stixhttps://api.datadoghq.com/api/v2/security/threat-intel/stixhttps://api.us3.datadoghq.com/api/v2/security/threat-intel/stixhttps://api.us5.datadoghq.com/api/v2/security/threat-intel/stix

Overview

Ingest a STIX 2.1 bundle containing threat intelligence indicators. Only indicator objects are processed. Supported indicator patterns contain IPv4 addresses, IPv6 addresses, domain names, or SHA-256 file hashes.

Non-indicator objects are ignored and are not included in the response counters. Indicator objects with unsupported STIX versions or patterns that produce no supported observable values increment the unsupported counter. Patterns that cannot be parsed increment the invalid counter. Processing is best effort, so valid supported indicators in the same bundle are still added.

A successful response means ingestion has completed. Reference-table materialization and enrichment happen asynchronously. Requests are limited to 50 MB as received, 100 MB after decompression, and 10 requests per second per API key. Gzip-compressed request bodies are supported.

This endpoint requires the reference_tables_write permission.

Arguments

Header Parameters

Name

Type

Description

ti_vendor [required]

string

Vendor identifier for the feed. The value must not exceed 10 characters. Datadog normalizes the accepted value to lowercase, converts non-alphanumeric characters to underscores, and trims leading and trailing underscores.

Content-Encoding

string

Content encoding for the request body. Use gzip for a compressed STIX bundle.

Request

Body Data (required)

A STIX 2.1 bundle containing indicator objects. The request body must not exceed 50 MB as received or 100 MB after decompression.

Expand All

Field

Type

Description

<any-key>

{
  "id": "bundle--44444444-4444-4444-8444-444444444444",
  "objects": [
    {
      "created": "2026-07-22T12:00:00Z",
      "id": "indicator--55555555-5555-4555-8555-555555555555",
      "modified": "2026-07-22T12:00:00Z",
      "pattern": "[ipv4-addr:value = '198.51.100.42']",
      "pattern_type": "stix",
      "spec_version": "2.1",
      "type": "indicator",
      "valid_from": "2026-07-22T12:00:00Z"
    }
  ],
  "spec_version": "2.1",
  "type": "bundle"
}

Response

OK

The response from a completed STIX ingestion request.

Expand All

Field

Type

Description

data [required]

object

The JSON:API resource describing the completed STIX ingestion request.

attributes [required]

object

Counters describing the result of the STIX ingestion request.

accepted [required]

int64

The number of supported indicators accepted.

invalid [required]

int64

The number of indicators with patterns that could not be parsed.

unsupported [required]

int64

The number of indicator objects with an unsupported STIX version or a pattern that produced no supported observable values.

id [required]

string

The normalized vendor identifier.

type [required]

enum

The STIX ingestion resource type. Allowed enum values: threat-intel-stix-ingest

{
  "data": {
    "attributes": {
      "accepted": 1,
      "invalid": 0,
      "unsupported": 0
    },
    "id": "acme",
    "type": "threat-intel-stix-ingest"
  }
}

Bad Request

API error response.

Expand All

Field

Type

Description

errors [required]

[object]

A list of errors.

detail

string

A human-readable explanation specific to this occurrence of the error.

meta

object

Non-standard meta-information about the error

source

object

References to the source of the error.

header

string

A string indicating the name of a single request header which caused the error.

parameter

string

A string indicating which URI query parameter caused the error.

pointer

string

A JSON pointer to the value in the request document that caused the error.

status

string

Status code of the response.

title

string

Short human-readable summary of the error.

{
  "errors": [
    {
      "detail": "Missing required attribute in body",
      "meta": {},
      "source": {
        "header": "Authorization",
        "parameter": "limit",
        "pointer": "/data/attributes/title"
      },
      "status": "400",
      "title": "Bad Request"
    }
  ]
}

Unauthorized

API error response.

Expand All

Field

Type

Description

errors [required]

[string]

A list of errors.

{
  "errors": [
    "Bad Request"
  ]
}

Forbidden

API error response.

Expand All

Field

Type

Description

errors [required]

[string]

A list of errors.

{
  "errors": [
    "Bad Request"
  ]
}

The request body exceeds 50 MB as received or 100 MB after decompression.

API error response.

Expand All

Field

Type

Description

errors [required]

[object]

A list of errors.

detail

string

A human-readable explanation specific to this occurrence of the error.

meta

object

Non-standard meta-information about the error

source

object

References to the source of the error.

header

string

A string indicating the name of a single request header which caused the error.

parameter

string

A string indicating which URI query parameter caused the error.

pointer

string

A JSON pointer to the value in the request document that caused the error.

status

string

Status code of the response.

title

string

Short human-readable summary of the error.

{
  "errors": [
    {
      "detail": "Missing required attribute in body",
      "meta": {},
      "source": {
        "header": "Authorization",
        "parameter": "limit",
        "pointer": "/data/attributes/title"
      },
      "status": "400",
      "title": "Bad Request"
    }
  ]
}

Too many requests

API error response.

Expand All

Field

Type

Description

errors [required]

[object]

A list of errors.

detail

string

A human-readable explanation specific to this occurrence of the error.

meta

object

Non-standard meta-information about the error

source

object

References to the source of the error.

header

string

A string indicating the name of a single request header which caused the error.

parameter

string

A string indicating which URI query parameter caused the error.

pointer

string

A JSON pointer to the value in the request document that caused the error.

status

string

Status code of the response.

title

string

Short human-readable summary of the error.

{
  "errors": [
    {
      "detail": "Missing required attribute in body",
      "meta": {},
      "source": {
        "header": "Authorization",
        "parameter": "limit",
        "pointer": "/data/attributes/title"
      },
      "status": "400",
      "title": "Bad Request"
    }
  ]
}

The STIX ingestion service returned an error while processing the request.

API error response.

Expand All

Field

Type

Description

errors [required]

[object]

A list of errors.

detail

string

A human-readable explanation specific to this occurrence of the error.

meta

object

Non-standard meta-information about the error

source

object

References to the source of the error.

header

string

A string indicating the name of a single request header which caused the error.

parameter

string

A string indicating which URI query parameter caused the error.

pointer

string

A JSON pointer to the value in the request document that caused the error.

status

string

Status code of the response.

title

string

Short human-readable summary of the error.

{
  "errors": [
    {
      "detail": "Missing required attribute in body",
      "meta": {},
      "source": {
        "header": "Authorization",
        "parameter": "limit",
        "pointer": "/data/attributes/title"
      },
      "status": "400",
      "title": "Bad Request"
    }
  ]
}

The STIX ingestion service is temporarily unavailable.

API error response.

Expand All

Field

Type

Description

errors [required]

[object]

A list of errors.

detail

string

A human-readable explanation specific to this occurrence of the error.

meta

object

Non-standard meta-information about the error

source

object

References to the source of the error.

header

string

A string indicating the name of a single request header which caused the error.

parameter

string

A string indicating which URI query parameter caused the error.

pointer

string

A JSON pointer to the value in the request document that caused the error.

status

string

Status code of the response.

title

string

Short human-readable summary of the error.

{
  "errors": [
    {
      "detail": "Missing required attribute in body",
      "meta": {},
      "source": {
        "header": "Authorization",
        "parameter": "limit",
        "pointer": "/data/attributes/title"
      },
      "status": "400",
      "title": "Bad Request"
    }
  ]
}

Code Example

                          ## default
# 

# Curl command
curl -X POST "https://api.ap1.datadoghq.com"https://api.ap2.datadoghq.com"https://api.datadoghq.eu"https://api.ddog-gov.com"https://api.us2.ddog-gov.com"https://api.uk1.datadoghq.com"https://api.datadoghq.com"https://api.us3.datadoghq.com"https://api.us5.datadoghq.com/api/v2/security/threat-intel/stix" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "ti_vendor: acme" \ -H "DD-API-KEY: ${DD_API_KEY}" \ -H "DD-APPLICATION-KEY: ${DD_APP_KEY}" \ -d @- << EOF { "id": "bundle--11111111-1111-4111-8111-111111111111", "objects": [ { "created": "2026-07-22T12:00:00Z", "id": "indicator--22222222-2222-4222-8222-222222222222", "modified": "2026-07-22T12:00:00Z", "pattern": "[ipv4-addr:value = '198.51.100.42']", "pattern_type": "stix", "spec_version": "2.1", "type": "indicator", "valid_from": "2026-07-22T12:00:00Z" } ], "spec_version": "2.1", "type": "bundle" } EOF
// Ingest STIX threat intelligence returns "OK" response

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"time"

	"github.com/DataDog/datadog-api-client-go/v2/api/datadog"
	"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2"
)

func main() {
	body := datadogV2.STIXBundleRequest{
		Id: "bundle--44444444-4444-4444-8444-444444444444",
		Objects: []datadogV2.STIXObject{
			{
				Created:     datadog.PtrTime(time.Date(2026, 7, 22, 12, 0, 0, 0, time.UTC)),
				Id:          "indicator--55555555-5555-4555-8555-555555555555",
				Modified:    datadog.PtrTime(time.Date(2026, 7, 22, 12, 0, 0, 0, time.UTC)),
				Pattern:     datadog.PtrString("[ipv4-addr:value = '198.51.100.42']"),
				PatternType: datadogV2.STIXPATTERNTYPE_STIX.Ptr(),
				SpecVersion: datadog.PtrString("2.1"),
				Type:        "indicator",
				ValidFrom:   datadog.PtrTime(time.Date(2026, 7, 22, 12, 0, 0, 0, time.UTC)),
			},
		},
		SpecVersion: datadogV2.STIXSPECVERSION_VERSION_2_1.Ptr(),
		Type:        datadogV2.STIXBUNDLETYPE_BUNDLE,
	}
	ctx := datadog.NewDefaultContext(context.Background())
	configuration := datadog.NewConfiguration()
	configuration.SetUnstableOperationEnabled("v2.AddSTIXThreatIntel", true)
	apiClient := datadog.NewAPIClient(configuration)
	api := datadogV2.NewThreatIntelligenceApi(apiClient)
	resp, r, err := api.AddSTIXThreatIntel(ctx, "Acme-Inc", body, *datadogV2.NewAddSTIXThreatIntelOptionalParameters())

	if err != nil {
		fmt.Fprintf(os.Stderr, "Error when calling `ThreatIntelligenceApi.AddSTIXThreatIntel`: %v\n", err)
		fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
	}

	responseContent, _ := json.MarshalIndent(resp, "", "  ")
	fmt.Fprintf(os.Stdout, "Response from `ThreatIntelligenceApi.AddSTIXThreatIntel`:\n%s\n", responseContent)
}

Instructions

First install the library and its dependencies and then save the example to main.go and run following commands:

    
DD_SITE="datadoghq.comus3.datadoghq.comus5.datadoghq.comdatadoghq.euap1.datadoghq.comap2.datadoghq.comuk1.datadoghq.comddog-gov.comus2.ddog-gov.com" DD_API_KEY="<DD_API_KEY>" DD_APP_KEY="<DD_APP_KEY>" go run "main.go"
// Ingest STIX threat intelligence returns "OK" response

import com.datadog.api.client.ApiClient;
import com.datadog.api.client.ApiException;
import com.datadog.api.client.v2.api.ThreatIntelligenceApi;
import com.datadog.api.client.v2.model.STIXBundleRequest;
import com.datadog.api.client.v2.model.STIXBundleType;
import com.datadog.api.client.v2.model.STIXIngestResponse;
import com.datadog.api.client.v2.model.STIXObject;
import com.datadog.api.client.v2.model.STIXPatternType;
import com.datadog.api.client.v2.model.STIXSpecVersion;
import java.time.OffsetDateTime;
import java.util.Collections;

public class Example {
  public static void main(String[] args) {
    ApiClient defaultClient = ApiClient.getDefaultApiClient();
    defaultClient.setUnstableOperationEnabled("v2.addSTIXThreatIntel", true);
    ThreatIntelligenceApi apiInstance = new ThreatIntelligenceApi(defaultClient);

    STIXBundleRequest body =
        new STIXBundleRequest()
            .id("bundle--44444444-4444-4444-8444-444444444444")
            .objects(
                Collections.singletonList(
                    new STIXObject()
                        .created(OffsetDateTime.parse("2026-07-22T12:00:00Z"))
                        .id("indicator--55555555-5555-4555-8555-555555555555")
                        .modified(OffsetDateTime.parse("2026-07-22T12:00:00Z"))
                        .pattern("[ipv4-addr:value = '198.51.100.42']")
                        .patternType(STIXPatternType.STIX)
                        .specVersion("2.1")
                        .type("indicator")
                        .validFrom(OffsetDateTime.parse("2026-07-22T12:00:00Z"))))
            .specVersion(STIXSpecVersion.VERSION_2_1)
            .type(STIXBundleType.BUNDLE);

    try {
      STIXIngestResponse result = apiInstance.addSTIXThreatIntel("Acme-Inc", body);
      System.out.println(result);
    } catch (ApiException e) {
      System.err.println("Exception when calling ThreatIntelligenceApi#addSTIXThreatIntel");
      System.err.println("Status code: " + e.getCode());
      System.err.println("Reason: " + e.getResponseBody());
      System.err.println("Response headers: " + e.getResponseHeaders());
      e.printStackTrace();
    }
  }
}

Instructions

First install the library and its dependencies and then save the example to Example.java and run following commands:

    
DD_SITE="datadoghq.comus3.datadoghq.comus5.datadoghq.comdatadoghq.euap1.datadoghq.comap2.datadoghq.comuk1.datadoghq.comddog-gov.comus2.ddog-gov.com" DD_API_KEY="<DD_API_KEY>" DD_APP_KEY="<DD_APP_KEY>" java "Example.java"
"""
Ingest STIX threat intelligence returns "OK" response
"""

from datadog_api_client import ApiClient, Configuration
from datadog_api_client.v2.api.threat_intelligence_api import ThreatIntelligenceApi
from datadog_api_client.v2.model.stix_bundle_request import STIXBundleRequest
from datadog_api_client.v2.model.stix_bundle_type import STIXBundleType
from datadog_api_client.v2.model.stix_object import STIXObject
from datadog_api_client.v2.model.stix_pattern_type import STIXPatternType
from datadog_api_client.v2.model.stix_spec_version import STIXSpecVersion
from datetime import datetime
from dateutil.tz import tzutc

body = STIXBundleRequest(
    id="bundle--44444444-4444-4444-8444-444444444444",
    objects=[
        STIXObject(
            created=datetime(2026, 7, 22, 12, 0, tzinfo=tzutc()),
            id="indicator--55555555-5555-4555-8555-555555555555",
            modified=datetime(2026, 7, 22, 12, 0, tzinfo=tzutc()),
            pattern="[ipv4-addr:value = '198.51.100.42']",
            pattern_type=STIXPatternType.STIX,
            spec_version="2.1",
            type="indicator",
            valid_from=datetime(2026, 7, 22, 12, 0, tzinfo=tzutc()),
        ),
    ],
    spec_version=STIXSpecVersion.VERSION_2_1,
    type=STIXBundleType.BUNDLE,
)

configuration = Configuration()
configuration.unstable_operations["add_stix_threat_intel"] = True
with ApiClient(configuration) as api_client:
    api_instance = ThreatIntelligenceApi(api_client)
    response = api_instance.add_stix_threat_intel(ti_vendor="Acme-Inc", body=body)

    print(response)

Instructions

First install the library and its dependencies and then save the example to example.py and run following commands:

    
DD_SITE="datadoghq.comus3.datadoghq.comus5.datadoghq.comdatadoghq.euap1.datadoghq.comap2.datadoghq.comuk1.datadoghq.comddog-gov.comus2.ddog-gov.com" DD_API_KEY="<DD_API_KEY>" DD_APP_KEY="<DD_APP_KEY>" python3 "example.py"
# Ingest STIX threat intelligence returns "OK" response

require "datadog_api_client"
DatadogAPIClient.configure do |config|
  config.unstable_operations["v2.add_stix_threat_intel".to_sym] = true
end
api_instance = DatadogAPIClient::V2::ThreatIntelligenceAPI.new

body = DatadogAPIClient::V2::STIXBundleRequest.new({
  id: "bundle--44444444-4444-4444-8444-444444444444",
  objects: [
    DatadogAPIClient::V2::STIXObject.new({
      created: "2026-07-22T12:00:00Z",
      id: "indicator--55555555-5555-4555-8555-555555555555",
      modified: "2026-07-22T12:00:00Z",
      pattern: "[ipv4-addr:value = '198.51.100.42']",
      pattern_type: DatadogAPIClient::V2::STIXPatternType::STIX,
      spec_version: "2.1",
      type: "indicator",
      valid_from: "2026-07-22T12:00:00Z",
    }),
  ],
  spec_version: DatadogAPIClient::V2::STIXSpecVersion::VERSION_2_1,
  type: DatadogAPIClient::V2::STIXBundleType::BUNDLE,
})
p api_instance.add_stix_threat_intel("Acme-Inc", body)

Instructions

First install the library and its dependencies and then save the example to example.rb and run following commands:

    
DD_SITE="datadoghq.comus3.datadoghq.comus5.datadoghq.comdatadoghq.euap1.datadoghq.comap2.datadoghq.comuk1.datadoghq.comddog-gov.comus2.ddog-gov.com" DD_API_KEY="<DD_API_KEY>" DD_APP_KEY="<DD_APP_KEY>" rb "example.rb"
// Ingest STIX threat intelligence returns "OK" response
use chrono::{DateTime, Utc};
use datadog_api_client::datadog;
use datadog_api_client::datadogV2::api_threat_intelligence::AddSTIXThreatIntelOptionalParams;
use datadog_api_client::datadogV2::api_threat_intelligence::ThreatIntelligenceAPI;
use datadog_api_client::datadogV2::model::STIXBundleRequest;
use datadog_api_client::datadogV2::model::STIXBundleType;
use datadog_api_client::datadogV2::model::STIXObject;
use datadog_api_client::datadogV2::model::STIXPatternType;
use datadog_api_client::datadogV2::model::STIXSpecVersion;

#[tokio::main]
async fn main() {
    let body = STIXBundleRequest::new(
        "bundle--44444444-4444-4444-8444-444444444444".to_string(),
        vec![STIXObject::new(
            "indicator--55555555-5555-4555-8555-555555555555".to_string(),
            "indicator".to_string(),
        )
        .created(
            DateTime::parse_from_rfc3339("2026-07-22T12:00:00+00:00")
                .expect("Failed to parse datetime")
                .with_timezone(&Utc),
        )
        .modified(
            DateTime::parse_from_rfc3339("2026-07-22T12:00:00+00:00")
                .expect("Failed to parse datetime")
                .with_timezone(&Utc),
        )
        .pattern("[ipv4-addr:value = '198.51.100.42']".to_string())
        .pattern_type(STIXPatternType::STIX)
        .spec_version("2.1".to_string())
        .valid_from(
            DateTime::parse_from_rfc3339("2026-07-22T12:00:00+00:00")
                .expect("Failed to parse datetime")
                .with_timezone(&Utc),
        )],
        STIXBundleType::BUNDLE,
    )
    .spec_version(STIXSpecVersion::VERSION_2_1);
    let mut configuration = datadog::Configuration::new();
    configuration.set_unstable_operation_enabled("v2.AddSTIXThreatIntel", true);
    let api = ThreatIntelligenceAPI::with_config(configuration);
    let resp = api
        .add_stix_threat_intel(
            "Acme-Inc".to_string(),
            body,
            AddSTIXThreatIntelOptionalParams::default(),
        )
        .await;
    if let Ok(value) = resp {
        println!("{:#?}", value);
    } else {
        println!("{:#?}", resp.unwrap_err());
    }
}

Instructions

First install the library and its dependencies and then save the example to src/main.rs and run following commands:

    
DD_SITE="datadoghq.comus3.datadoghq.comus5.datadoghq.comdatadoghq.euap1.datadoghq.comap2.datadoghq.comuk1.datadoghq.comddog-gov.comus2.ddog-gov.com" DD_API_KEY="<DD_API_KEY>" DD_APP_KEY="<DD_APP_KEY>" cargo run
/**
 * Ingest STIX threat intelligence returns "OK" response
 */

import { client, v2 } from "@datadog/datadog-api-client";

const configuration = client.createConfiguration();
configuration.unstableOperations["v2.addSTIXThreatIntel"] = true;
const apiInstance = new v2.ThreatIntelligenceApi(configuration);

const params: v2.ThreatIntelligenceApiAddSTIXThreatIntelRequest = {
  body: {
    id: "bundle--44444444-4444-4444-8444-444444444444",
    objects: [
      {
        created: new Date(2026, 7, 22, 12, 0, 0, 0),
        id: "indicator--55555555-5555-4555-8555-555555555555",
        modified: new Date(2026, 7, 22, 12, 0, 0, 0),
        pattern: "[ipv4-addr:value = '198.51.100.42']",
        patternType: "stix",
        specVersion: "2.1",
        type: "indicator",
        validFrom: new Date(2026, 7, 22, 12, 0, 0, 0),
      },
    ],
    specVersion: "2.1",
    type: "bundle",
  },
  tiVendor: "Acme-Inc",
};

apiInstance
  .addSTIXThreatIntel(params)
  .then((data: v2.STIXIngestResponse) => {
    console.log(
      "API called successfully. Returned data: " + JSON.stringify(data)
    );
  })
  .catch((error: any) => console.error(error));

Instructions

First install the library and its dependencies and then save the example to example.ts and run following commands:

    
DD_SITE="datadoghq.comus3.datadoghq.comus5.datadoghq.comdatadoghq.euap1.datadoghq.comap2.datadoghq.comuk1.datadoghq.comddog-gov.comus2.ddog-gov.com" DD_API_KEY="<DD_API_KEY>" DD_APP_KEY="<DD_APP_KEY>" tsc "example.ts"