# Chronicle API ingestion methods

Supported in:

This document describes how the Ingestion methods in the Chronicle API
forward logs directly to your Google Security Operations instance. This process
eliminates the need for additional hardware or software (for example,
forwarders) in your environment.

The Chronicle API service for Google SecOps improves, expands,
and adds to the functionality of existing ingestion management API methods and
partner API services, for example, the [Chronicle Ingestion
API and Partner API services of Legacy Ingestion API](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-api).

| Chronicle API method | Description | IAM permission required |
|---|---|---|
| [ImportEvents](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#importevents) | Import UDM events. | `chronicle.googleapis.com/events.import` |
| [ImportLogs](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#importlogs) | Import unstructured log entries. | `chronicle.googleapis.com/logs.import` |
| [ImportEntities](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#importentities) | Import entity context. | `chronicle.googleapis.com/entities.import` |
| [ListLogTypes](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#listlogtypes) | List supported log types. | `chronicle.googleapis.com/logTypes.list` |

For information about mapping Ingestion API methods to the Chronicle API, see
[SIEM API endpoint mapping](https://docs.cloud.google.com/chronicle/docs/administration/siem-endpoint-mapping-table).

## Explore the Chronicle API

The Chronicle API is a RESTful API with a JSON payload. You
can develop systems to call Chronicle API methods
directly and forward logs to Google SecOps. Managed Security
Service Providers (MSSPs) and your
[Technology Partners](https://docs.cloud.google.com/chronicle/docs/technology-partner-program) can use
these API methods to send logs to Google SecOps.

## Forward log data

If you've formatted your log data using Google SecOps Unified
Data Model (UDM), you can forward UDM events to your
Google SecOps account using the `ImportEvents` endpoint.
Google SecOps can more effectively process this data and improve
threat detection because it standardizes UDM events. For information about
converting raw logs to UDM, see [Format log data as UDM](https://docs.cloud.google.com/chronicle/docs/unified-data-model/format-events-as-udm).

You can also forward your data to Google SecOps as unstructured
logs using the `ImportLogs` endpoint. Your unstructured log data is normalized
within the Google SecOps infrastructure and made available to you
through the Google SecOps console. However, some information may be
difficult to extract from the unstructured log data and might only be searchable
using the Raw Log Scan.

> [!NOTE]
> **Note:** Whenever possible, we recommend forwarding your data to Google SecOps as UDM events.

> [!IMPORTANT]
> **Important:** Occasionally, logs sent using Ingestion methods or streaming endpoints (Webhook, Pub/Sub, Amazon Data Firehose) don't contain separate log lines. When this happens, Google SecOps treats multiple lines as a single entry, causing parsing errors. To prevent this, make sure that all log lines start on a new line.

### Batch deduplication

Google SecOps uses a batch-level deduplication mechanism to prevent ingesting duplicate data. This process ensures that Google SecOps avoids processing the exact same set of log data from the same source multiple times, but still allows it to ingest similar data categorized under different log types.

#### How batch deduplication works

When you send a batch of logs, Google SecOps generates a unique batch ID by hashing the customer ID and the *content of the log entries* within the batch, including raw log data and any Unified Data Model (UDM) fields. The batch ID hash *does not* include the log type or other metadata fields like namespaces, labels, or the feed ID.

Google SecOps performs deduplication *only within the context of a single log type* for a specific customer. Google SecOps does not consider batches with identical content but different log types as duplicates and ingests them.

If a newly generated batch ID matches an existing batch ID for the same customer ID and log type, Google SecOps rejects the entire new batch as a duplicate.

### Grant IAM permissions

To use Ingestion methods in the Chronicle API, you must grant the corresponding
IAM permissions from the preceding table to the identity (either
the service account or the external identity principal) used for authentication.

- **Custom role (recommended)** : [Create a custom IAM role](https://docs.cloud.google.com/iam/docs/creating-custom-roles#creating) with the required permissions, and [grant](https://docs.cloud.google.com/iam/docs/granting-changing-revoking-access#grant-single-role) the custom role to the service account or the external identity principal.
- **Predefined role** : [Grant](https://docs.cloud.google.com/iam/docs/granting-changing-revoking-access#grant-single-role) the [Chronicle API Editor](https://docs.cloud.google.com/iam/docs/roles-permissions/chronicle#chronicle.editor) IAM role to the service account or the external identity principal. This role provides broader permissions than required for Ingestion methods.

Note that IAM changes can take a few minutes to propagate.

## Client libraries

Client libraries provide code samples for using Ingestion methods, offering
a quick way to access these methods from a supported language. Although you can
use the Ingestion methods by making raw requests to the server, client libraries offer
simplifications that significantly reduce the amount of code you need to write.
Client libraries for Ingestion methods are available on GitHub, in the public
[Google secops-wrapper
examples](https://github.com/google/secops-wrapper/tree/main/examples) folder.

### Example: UDM event ingestion

The following client library Python script,
[ingest_udm_events.py](https://github.com/google/secops-wrapper/blob/main/examples/ingest_udm_events.py),
demonstrates how to ingest UDM events into Google SecOps, using
the `secops` library to interact with the Chronicle API.

#### Script functions

The script uses a series of functions to demonstrate each scenario.

- Event creation

  The following functions create sample UDM events that include metadata, such as
  `id`, `event_timestamp`, `event_type`, `product_name`, and `vendor_name`,
  along with specific details for each event type (for example, `IP addresses`,
  `ports`, `command lines`, `MD5 hashes`):
  - `create_sample_network_event()` generates a network connection event.
  - `create_sample_process_event()` generates a process launch event.
- Ingestion

  The following functions send (one or more) Chronicle client objects and UDM events to Google SecOps:
  - `ingest_single_event()` sends a single UDM event (a network event in this example) to the API.
  - `ingest_multiple_events()` sends a list of UDM events (a network event and a process event) to Google SecOps in a single API call.
  - `ingest_event_without_id()` shows that if you omit the `id` field, Google SecOps automatically generates one during ingestion.

#### Run the script

The `main()` function parses command-line arguments for `customer-id`,
`project-id`, and `region` to configure the **Chronicle** client. It then calls
the ingestion example functions to demonstrate each scenario. The
script includes error handling to catch `APIError` exceptions during ingestion.

## Regional endpoints

Your API endpoint depends on the region where your customer account is
provisioned.
Google SecOps provides the following list of [Regional service endpoints](https://docs.cloud.google.com/chronicle/docs/reference/rest?rep_location=us#regional-service-endpoint).

## Set up domain allowlisting

The Google SecOps push Ingestion API mechanism requires *domain allowlisting* to support your egress proxy settings.

Allowlist the following domains for egress traffic:

- **OAuth / authorization** :
  - `oauth2.googleapis.com`
  - `www.googleapis.com` (specifically for legacy or fallback token requests)
- **Google SecOps ingestion API**:

  - `<region>-chronicle.googleapis.com` (the modern Chronicle Ingestion API)---for regional ingestion endpoints, for example, `europe-chronicle.googleapis.com` or `asia-northeast1-chronicle.googleapis.com`.  
    For the complete list, see [Regional service endpoints](https://docs.cloud.google.com/chronicle/docs/reference/rest#service-chronicle.googleapis.com).

  > [!NOTE]
  > **Note:** The legacy Backstory Ingestion API uses `malachiteingestion-pa.googleapis.com`. For the regional endpoints, see [Regional endpoints](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-api#regional-endpoints).

#### Automate the handling of IP-range updates

Because Google's public IP address ranges *are updated dynamically* , Google recommends that you configure your firewall to periodically fetch and parse the JSON file with the [Google Services IP ranges](https://www.gstatic.com/ipranges/goog.json).

You can use the following Python script to create a list of IP address ranges that include those used by the default domains for Google APIs and services. For information about running this script, see [How to run](https://github.com/GoogleCloudPlatform/networking-tools-python/tree/main/tools/cidr#how-to-run).

    from __future__ import print_function

    import json

    try:
        from urllib import urlopen
    except ImportError:
        from urllib.request import urlopen
        from urllib.error import HTTPError

    import netaddr

    IPRANGE_URLS = {
        "goog": "https://www.gstatic.com/ipranges/goog.json",
        "cloud": "https://www.gstatic.com/ipranges/cloud.json",
    }

    def read_url(url):
        try:
            return json.loads(urlopen(url).read())
        except (IOError, HTTPError):
            print("ERROR: Invalid HTTP response from %s" % url)
        except json.decoder.JSONDecodeError:
            print("ERROR: Could not parse HTTP response from %s" % url)

    def get_data(link):
        data = read_url(link)
        if data:
            print("{} published: {}".format(link, data.get("creationTime")))
            cidrs = netaddr.IPSet()
            for e in data["prefixes"]:
                if "ipv4Prefix" in e:
                    cidrs.add(e.get("ipv4Prefix"))
                if "ipv6Prefix" in e:
                    cidrs.add(e.get("ipv6Prefix"))
            return cidrs

    def main():
        cidrs = {group: get_data(link) for group, link in IPRANGE_URLS.items()}
        if len(cidrs) != 2:
            raise ValueError("ERROR: Could not process data from Google")
        print("IP ranges for Google APIs and services default domains:")
        for ip in (cidrs["goog"] - cidrs["cloud"]).iter_cidrs():
            print(ip)

    if __name__ == "__main__":
        main()

> [!NOTE]
> **Note:** The preceding subtraction script (`goog.json - cloud.json`) is intended only for egress proxy rules with push ingestion API methods. Don't use this script for pull feeds, as pull feeds require both `goog.json` and `cloud.json` IP ranges.

## API behavior and limitations

- Limitations:

  - Maximum individual log size: 4 MB. Logs larger than this limit aren't ingested into Google SecOps. This is higher than the 1 MB per line limit imposed on some [legacy ingestion pathways and certain HTTPS push feeds](https://docs.cloud.google.com/chronicle/docs/reference/service-limits#ingestion_rate)
  - Maximum batch size (uncompressed): 4 MB
  - Maximum request size: 4 MB
  - Request timeout: 60 seconds
- Best practices:

  - Request timeout: Set to 60 seconds
  - Optimal log lines per batch: approximately 1,000
  - Optimal batch size: approximately 2 MB

## API reference

Use the Ingestion methods in this section to ingest data into your Google SecOps instance.

### ImportEvents

Use this method to import UDM events into Google SecOps.

> [!IMPORTANT]
> **Important:** Direct UDM ingestion is a passthrough. When you ingest events formatted as UDM (with `log_type = "UDM"`), Google SecOps writes the data directly to the UDM database without running any parser or normalization pipeline. Any missing fields or dropped records are client-side schema validation errors (such as field casing or nesting mismatches), not parser execution failures. Confirm that incoming JSON payloads strictly match the field names, types, and hierarchy in the [UDM field list](https://docs.cloud.google.com/chronicle/docs/reference/udm-field-list) and check API responses for HTTP `400 INVALID_ARGUMENT` errors.

| API version | Reference documentation |
|---|---|
| `v1alpha` | [Method: events.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.events/import) |
| `v1beta` | [Method: events.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1beta/projects.locations.instances.events/import) |
| `v1` | [Method: events.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1/projects.locations.instances.events/import) |

**Full name:** `projects.locations.instances.events.import`

#### Request

| API version | Request |
|---|---|
| `v1alpha` | `POST https://{region}-chronicle.googleapis.com/v1alpha/{parent}/events:import` |
| `v1beta` | `POST https://{region}-chronicle.googleapis.com/v1beta/{parent}/events:import` |
| `v1` | `POST https://{region}-chronicle.googleapis.com/v1/{parent}/events:import` |

##### Path parameters

| Field | Value | Required | Description |
|---|---|---|---|
| `{region}` | string | Yes | The location for the service endpoint. Choose from the [Regional service endpoint](https://docs.cloud.google.com/chronicle/docs/reference/rest?rep_location=us#regional-service-endpoint) list. |
| `{parent}` | string | Yes | The parent that owns this collection of events. Format: `projects/{project}/locations/{region}/instances/{instance}` |

#### Request body

The following example shows how to import log data in UDM format using the `ImportEvents` API method.

> [!NOTE]
> **Note:** The `<Noun>.mac` field accepts both uppercase and lowercase characters. `<Noun>` is `principal`, `src`, `target`, `observer`, `intermediary`, or `about`. Character values are converted and stored as lowercase.

> [!NOTE]
> **Note:** All events must be valid for the request to be successful. An error in one event causes the entire request to be rejected.

    {
      "parent": "projects/gcp_project_id/locations/us/instances/aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
      "inlineSource": {
        "events": [{
          "udm": {
            "metadata": {
              "eventTimestamp": "1970-01-01T03:25:45.000000123Z",
              "eventType": "USER_LOGIN",
              "vendorName": "Acme",
              "productName": "Acme SSO"
            },
            "principal": {
              "ip": ["10.1.2.3"]
            },
            "target": {
              "user": {
                "userid": "<REDACTED_PII>",
                "userDisplayName": "Mary Jane"
              },
              "application": "Acme Connect"
            },
            "extensions": {
              "auth": {
                "type": "MACHINE",
                "mechanism": ["NETWORK"]
              }
            }
          }
        }, {
          "udm": {
            "metadata": {
              "eventTimestamp": "1970-01-01T03:25:45.000000123Z",
              "eventType": "NETWORK_HTTP",
              "vendorName": "Acme",
              "productName": "Acme Proxy"
            },
            "principal": {
              "hostname": "host0",
              "ip": ["10.1.2.3"],
              "port": 6000
            },
            "target": {
              "hostname": "www.altostrat.com",
              "ip": ["198.51.100.68"],
              "port": 443,
              "url": "www.altostrat.com/images/logo.png"
            },
            "network": {
              "http": {
                "method": "GET",
                "responseCode": 200
              }
            }
          }
        }]
      }
    }

#### Body parameters

| Field | Value | Required | Description |
|---|---|---|---|
| `inlineSource` | object | Yes | The import source with the `events` to import, specified inline. |
| `events[]` | array | Yes | The events to import. |
| `events.udm` | object ([UDM](https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/UDM)) | Yes | The event data in UDM format. The object can contain the [events.udm object fields](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#events-udm-object-fields), shown in the following table. |

##### Events.udm object fields

| Field | Description |
|---|---|
| `metadata` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Metadata`)`` Event metadata, such as `timestamp` and `source product`. |
| `additional` | ``object (`https://protobuf.dev/reference/protobuf/google.protobuf#struct` format)`` Any important vendor-specific event data that can't be adequately represented within the formal sections of the UDM. |
| `principal` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Noun`)`` Represents the acting entity that originates the activity described in the event. The `principal` must include at least one machine detail (`hostname`, `MAC address`, `IP address`, `port`, product-specific identifiers like an `EDR asset ID`) or user detail (for example, `username`), and optionally include process details. It must not include any of the following fields: `email`, `files`, `registry keys` or `values`. |
| `src` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Noun`)`` Represents a source entity being acted upon by the participant, along with the device or process context for the source object (the machine where the source object resides). For example, if user `U` copies file `A` on machine `X` to file `B` on machine `Y`, both file `A` and machine `X` would be specified in the `src` portion of the UDM event. |
| `target` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Noun`)`` Represents a `target` entity being referenced by the event or an object on the `target` entity. For example, in a firewall connection from device `A` to device `B`, `A` is described as the `principal` and `B` is described as the `target`. For a process injection by process `C` into `target` process `D`, process `C` is described as the `principal` and process `D` is described as the `target`. |
| `intermediary[]` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Noun`)`` Represents details on one or more intermediate entities processing activity described in the event. This includes device details about a `proxy server` or `SMTP relay server`. If an active event (that has a `principal` and possibly `target`) passes through any intermediaries, they're added here. Intermediaries can impact the overall action, for example blocking or modifying an ongoing request. `A` rule of thumb here is that `principal`, `target`, and `description` of the initial action should be the same regardless of the intermediary or its action. A successful network connection from `A`-\>`B` should look the same in `principal`/`target`/`intermediary` as one blocked by firewall `C`: `principal`: `A`, `target`: `B` (`intermediary`: `C`). |
| `observer` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Noun`)`` Represents an `observer` entity, which is not a direct intermediary, but which observes and reports on the event in question. For example, a `packet sniffer` or `network-based vulnerability scanner`. |
| `about[]` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Noun`)`` Represents entities referenced by the event, that are not otherwise described in `principal`, `src`, `target`, `intermediary` or `observer`. For example, it can be used to track email file attachments, `domains`/`URLs`/`IPs` embedded within an email body, and DLLs that are loaded during a PROCESS_LAUNCH event. |
| `security_result[]` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/SecurityResult`)`` A list of security results. |
| `network` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Network`)`` All network details go here, including `sub-messages` with details on each `protocol` For example, `DHCP`, `DNS`, or `HTTP`. |
| `extensions` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/UDM#Extensions`)`` Place all core and event-specific metadata in this message, and use `Network` for protocol metadata instead of `Extensions`. |
| `extracted` | ``object (`https://protobuf.dev/reference/protobuf/google.protobuf#struct` format)`` Flattened fields extracted from the log. |

#### Response

You shouldn't receive a response unless there is an error in the method syntax.

#### Response error codes

See [HTTP response codes](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#http_response_codes) for common error codes.

### ImportLogs

Import log telemetry. Use this method to send unstructured log entries to Google SecOps in batches. Each batch of log data has a maximum size limit of 4 MB (uncompressed).

| API version | Reference documentation |
|---|---|
| `v1alpha` | [Method: logs.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.logTypes.logs/import) |
| `v1beta` | [Method: logs.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1beta/projects.locations.instances.logTypes.logs/import) |
| `v1` | [Method: logs.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1/projects.locations.instances.logTypes.logs/import) |

**Full name:** `projects.locations.instances.logTypes.logs.import`

#### Request

| API version | Request |
|---|---|
| `v1alpha` | `POST https://{region}-chronicle.googleapis.com/v1alpha/{parent}/logs:import` |
| `v1beta` | `POST https://{region}-chronicle.googleapis.com/v1beta/{parent}/logs:import` |
| `v1` | `POST https://{region}-chronicle.googleapis.com/v1/{parent}/logs:import` |

##### Path parameters

| Field | Value | Required | Description |
|---|---|---|---|
| `{region}` | string | Yes | The location for the service endpoint. Choose from the [Regional service endpoint](https://docs.cloud.google.com/chronicle/docs/reference/rest?rep_location=us#regional-service-endpoint) list. |
| `{parent}` | string | Yes | The parent that owns this collection of logs. Format: `projects/{project}/locations/{region}/instances/{instance}/logTypes/{log_type}` |

#### Request body

The following example shows how to format AZURE_AD log data from a source file, using the `ImportLogs` API method.

    {
      "parent": "projects/gcp_project_id/locations/us/instances/aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/logTypes/AZURE_AD",
      "inlineSource": {
        "logs": [{
          "data": "dGVzdC5sb2c=",
          "logEntryTime": "2025-06-25T06:07:51.000001234Z",
          "collectionTime": "2025-06-25T06:07:51.000000123Z",
          "labels": {
            "google": {
              "value": "dev",
              "rbacEnabled": true
            }
          }
        }],
        "sourceFilename": "source_filename.txt"
      }
    }

#### Body parameters

| Field | Value | Required | Description |
|---|---|---|---|
| `inlineSource` | object | Yes | The log data import source, with the `logs` specified inline. |
| `logs[]` | object | Yes | Log data to import. The object can contain the [log object fields](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#log-object-fields), shown in the following table. (v1alpha reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.logTypes.logs#Log`) (v1beta reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1beta/projects.locations.instances.logTypes.logs#Log`) (v1 reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1/projects.locations.instances.logTypes.logs#Log`) |
| `forwarder` | string | No | The forwarder sending the import request. |
| `source_filename` | string | No | Source filename. Populated for certain types of files processed by the outofband processor, which may have metadata encoded in it for use by the parser. |

##### Log object fields

| Field | Description |
|---|---|
| `name` | `string` Output only. The resource name of this log. Format: `projects/{project}/locations/{region}/instances/{instance}/logTypes/{log_type}/logs/{log}` |
| `data` | `string (https://developers.google.com/discovery/v1/type-format format)` Required. Raw data for the log entry. A base64-encoded string. |
| `logEntryTime` | ``string (`https://protobuf.dev/reference/protobuf/google.protobuf#timestamp` format)`` Required. Timestamp of the log entry. Uses RFC 3339, where generated output is always Z-normalized and uses 0, 3, 6 or 9 fractional digits. Offsets other than "Z" are also accepted. Examples: `"2014-10-02T15:01:23Z"`, `"2014-10-02T15:01:23.045123456Z"` or `"2014-10-02T15:01:23+05:30"`. |
| `collection_time` | ``string (`https://protobuf.dev/reference/protobuf/google.protobuf#timestamp` format)`` Required. The time at which the log entry was collected. This value must be after the `logEntryTime`.The format is RFC 3339. The field supports Z-normalized output using 0, 3, 6, or 9 fractional digits, and also accepts offsets other than "Z". Examples: `"2014-10-02T15:01:23Z"`, `"2014-10-02T15:01:23.045123456Z"`, or `"2014-10-02T15:01:23+05:30"`. |
| `environment_namespace` | `string` Optional. The user-configured environment namespace to identify the data domain the logs originated from. This namespace is used as a tag to identify the appropriate data domain for indexing and enrichment functionality. |
| `labels` | ``map (key: string, value: object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/LogLabel`))`` Optional. The user-configured custom metadata labels. An object containing a list of `"key": value` pairs. Example: `{ "name": "wrench", "mass": "1.3kg", "count": "3" }`. |
| `additionals` | ``object (`https://protobuf.dev/reference/protobuf/google.protobuf#struct` format)`` Optional. Metadata in JSON format. |

#### Response

You shouldn't receive a response unless there is an error in the method syntax.

#### Response error codes

See [HTTP response codes](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#http_response_codes) for common error codes.

### ImportEntities

Use this method to import entities into Google SecOps.

An entity provides additional context about an entity in a UDM event, like
`asset` or `user` details. For example, a `PROCESS_LAUNCH` event describes that
user `abc@example.corp` launched process `shady.exe`. The event does not include
information that user `abc@example.com` is a recently terminated employee who
administers a server storing finance data. Information stored in one or more
entities can add this additional context.

You are limited to 4MB of data per request.

| API version | Reference documentation |
|---|---|
| `v1alpha` | [Method: entities.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.entities/import) |
| `v1beta` | [Method: entities.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1beta/projects.locations.instances.entities/import) |
| `v1` | [Method: entities.import](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1/projects.locations.instances.entities/import) |

**Full name:** `projects.locations.instances.entities.import`

#### Request

| API version | Request |
|---|---|
| `v1alpha` | `POST https://{region}-chronicle.googleapis.com/v1alpha/{parent}/entities:import` |
| `v1beta` | `POST https://{region}-chronicle.googleapis.com/v1beta/{parent}/entities:import` |
| `v1` | `POST https://{region}-chronicle.googleapis.com/v1/{parent}/entities:import` |

##### Path parameters

| Field | Value | Required | Description |
|---|---|---|---|
| `{region}` | string | Yes | The location for the service endpoint. Choose from the [Regional service endpoint](https://docs.cloud.google.com/chronicle/docs/reference/rest?rep_location=us#regional-service-endpoint) list. |
| `{parent}` | string | Yes | The parent that owns this collection of entities. Format: `projects/{project}/locations/{region}/instances/{instance}` |

#### Request body

The following example shows how to import entities data using
the `ImportEntities` API method.

> [!NOTE]
> **Note:** The `entity.asset.mac` field accepts both uppercase and lowercase characters. Character values are converted and stored as lowercase.

    {
      "parent": "projects/gcp_project_id/locations/us/instances/aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
      "inlineSource": {
        "entities": [{
          "metadata": {
            "collectedTimestamp": "1970-01-01T03:25:45.000000124Z",
            "vendorName": "vendor",
            "productName": "product",
            "entityType": "USER"
          },
          "entity": {
            "user": {
              "userid": "google dev",
              "productObjectId": "dev google"
            }
          }
        }, {
          "metadata": {
            "collectedTimestamp": "1970-01-01T03:25:45.000000124Z",
            "vendorName": "vendor",
            "productName": "product",
            "entityType": "USER"
          },
          "entity": {
            "user": {
              "userid": "google dev",
              "productObjectId": "dev google"
            }
          }
        }],
        "logType": "AZURE_AD_CONTEXT"
      }
    }

#### Body parameters

| Field | Value | Required | Description |
|---|---|---|---|
| `inlineSource` | object | Yes | The import source with the `entities` to import, specified inline. |
| `entities[]` | object | Yes | The entities to import. The object can contain the [entity object fields](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#entity-object-fields), shown in the following table. (v1alpha reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.entities#Entity`) (v1beta reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1beta/projects.locations.instances.entities#Entity`) (v1 reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1/projects.locations.instances.entities#Entity`) |
| `log_type` | string | Yes | The log type of the log that this entity is created from. |

##### Entity object fields

| Field | Description |
|---|---|
| `metadata` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Entity#EntityMetadata`)`` Entity metadata, such as `timestamp` or `product` metadata. |
| `entity` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Noun`)`` Noun in the UDM event that this entity represents. |
| `additional` | ``object (`https://protobuf.dev/reference/protobuf/google.protobuf#struct` format)`` Important entity data that cannot be adequately represented within the formal sections of the Entity. |
| `risk_score` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/EntityRisk`)`` Entity risk scores resource. |
| `metric` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Entity#Metric`)`` Metric details of the entity. Used if EntityType is METRIC. |
| `relations[]` | ``object (`https://docs.cloud.google.com/chronicle/docs/reference/rest/Shared.Types/Entity#Relation`)`` One or more relationships between the entity (a) and other entities, including the relationship type and related entity. |

#### Response

If successful, the response body is empty.

#### Response error codes

See [HTTP response codes](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#http_response_codes) for common error codes.

### ListLogTypes

Use this method to retrieve a list of all the supported log types.

| API version | Reference documentation |
|---|---|
| `v1alpha` | [Method: logTypes.list](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.logTypes/list) |
| `v1beta` | [Method: logTypes.list](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1beta/projects.locations.instances.logTypes/list) |
| `v1` | [Method: logTypes.list](https://docs.cloud.google.com/chronicle/docs/reference/rest/v1/projects.locations.instances.logTypes/list) |

**Full name:** `projects.locations.instances.logTypes.list`

#### Request

| API version | Request |
|---|---|
| `v1alpha` | `GET https://{region}-chronicle.googleapis.com/v1alpha/{parent}/logTypes` |
| `v1beta` | `GET https://{region}-chronicle.googleapis.com/v1beta/{parent}/logTypes` |
| `v1` | `GET https://{region}-chronicle.googleapis.com/v1/{parent}/logTypes` |

##### Path parameters

| Field | Value | Required | Description |
|---|---|---|---|
| `{region}` | string | Yes | The location for the service endpoint. Choose from the [Regional service endpoint](https://docs.cloud.google.com/chronicle/docs/reference/rest?rep_location=us#regional-service-endpoint) list. |
| `{parent}` | string | Yes | The parent that owns this collection of log types. Format: `projects/{project}/locations/{region}/instances/{instance}` |

#### Query parameters

| Field | Description |
|---|---|
| `pageSize` | `integer` The maximum number of log types to return. The service may return fewer than this value. |
| `pageToken` | `string` A page token, received from a previous `ListLogTypes` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListLogTypes` must match the call that provided the page token. |
| `filter` | `string` Optional. A filter that follows AIP-160 guidelines. |

#### Request body

The request body must be empty.

#### Response

The following example shows the information returned from the ListLogTypes API method.

    {
      "logTypes": [{
        "name": "projects/gcp_project_id/locations/us/instances/aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/logTypes/A10_LOAD_BALANCER",
        "displayName": "A10 Load Balancer"
      }, {
        "name": "projects/gcp_project_id/locations/us/instances/aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/logTypes/ABNORMAL_SECURITY",
        "displayName": "Abnormal Security"
      }, {
        "name": "projects/gcp_project_id/locations/us/instances/aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/logTypes/ABSOLUTE",
        "displayName": "Absolute Mobile Device Management"
      }, {
        "name": "projects/gcp_project_id/locations/us/instances/aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/logTypes/ACALVIO",
        "displayName": "Acalvio"
      }, {
        "name": "projects/gcp_project_id/locations/us/instances/aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/logTypes/ACTIVE_IDENTITY_HID",
        "displayName": "Active Identity HID"
      }],
      "nextPageToken": "Qp4b7jgMSY3Byb2plY3RzL21hbGFjaGl0ZS1jYXRmb29kLWJ5b3Atc3RhZ2"
    }

#### Response fields

| Field | Description |
|---|---|
| `log_types[]` | `object` Log types from the specified Google SecOps instance. The object can contain the [logType object fields](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#logtype-object-fields), shown in the following table. (v1alpha reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.logTypes#LogType`) (v1beta reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1beta/projects.locations.instances.logTypes#LogType`) (v1 reference: `https://docs.cloud.google.com/chronicle/docs/reference/rest/v1/projects.locations.instances.logTypes#LogType`) |
| `next_page_token` | `string` A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. |

##### LogType object fields

| Field | Description |
|---|---|
| `name` | `string` Output only. The resource name of this log type. Format: `projects/{project}/locations/{region}/instances/{instance}/logTypes/{log_type}` |
| `custom_log_type_label` | `string` Output only. The custom log type label. |
| `display_name` | `string` Required. The display name of this log type. This is the tag used in YARA-l rules and search queries. |
| `golden` | `boolean` Output only. Whether a log type is a 'Golden' log type or not. Log types that support rapid customer onboarding are considered 'Golden' log types. |
| `product_source` | `string` Required. The display name of this log type when a user creates a feed. |
| `is_custom` | `boolean` Required. Whether the log type is custom or globally available. |

#### Response error codes

See [HTTP response codes](https://docs.cloud.google.com/chronicle/docs/reference/ingestion-methods#http_response_codes) for common error codes.

## Error handling

Here's what to do if an HTTP request fails, depending on the HTTP response code:

### HTTP response codes

- **400 Bad Request** : The request is invalid.  
  Check the error message for details. Don't retry without modification.
- **401 Unauthorized** : Authentication failed.  
  Check your credentials.
- **403 Forbidden** : Permission denied.  
  Make sure the caller has the correct IAM permissions.
- **404 Not Found** : The resource specified in the request doesn't exist.  
  Check the resource name.
- **429 Resource Exhausted** : Quota limit reached or rate limit exceeded.  
  Retry using *exponential backoff* , with a minimum delay of 30 seconds. If the request continues to fail, see [What to do when reaching the burst limit](https://docs.cloud.google.com/chronicle/docs/ingestion/burst-limits#burst-limit-actions).
- **500 Internal Server Error** : An error occurred on the server.  
  Retry using *exponential backoff*, with a minimum delay of 1 second.
- **503 Service Unavailable** : The service is temporarily unavailable.  
  Retry using *exponential backoff*, with a minimum delay of 1 second.

> [!NOTE]
> **Note:** *Exponential backoff* is a strategy that increases the wait time between retries for failed requests to avoid overloading a service. For example, a request that fails after one second might be retried after two seconds, then four seconds, then eight seconds, and follow this pattern.

### View Chronicle API HTTP errors

You can view Chronicle API HTTP errors for your Bring Your Own Project (BYOP) projects using the Metrics Explorer in [Cloud Monitoring](https://docs.cloud.google.com/apis/docs/monitoring#using).

To see the HTTP errors for your BYOP project, follow these steps:

1. Go to the **Google Cloud console** and select your project.
2. Go to **Monitoring** \> **Metrics Explorer**.
3. Click **Select a Metric**.
4. Choose **Consumed API** as the resource type.
5. Choose **API request count** (serviceruntime.googleapis.com/api/request_count) as the metric.
6. Add filters to narrow down the results:
   - `service`: Specify the API service name (e.g., compute.googleapis.com).
   - `response_code_class`: Filter for 4xx or 5xx.
   - `method`: Specify the API method.
7. You can group the results to analyze the errors, for example, by: `method`, `response_code`, or `service`.

## Frequently asked questions

**Can customers create an allowlist of specific public IP addresses permitted to connect to the collector API endpoint, or is another form of client authorization supported?**

For push ingestion using the Chronicle API, Google SecOps doesn't support ingress IP allowlisting. Any connection with a valid API key can connect to the collector API endpoint. For pull-based data feeds, see [Set up IP allowlisting](https://docs.cloud.google.com/chronicle/docs/reference/feed-management-api#ip-allowlist).

**Do you support standard HTTP GZIP compression (for example, Accept-Encoding: gzip header)?**

Yes. The collector API endpoint supports standard HTTP GZIP compression using the `Accept-Encoding: gzip` header.

**Need more help?** [Get answers from Community members and Google SecOps professionals.](https://security.googlecloudcommunity.com/)