1Security
Reference

API Reference

The read-only REST API for pulling 1Security audit logs, monitoring alerts, and security alerts into a SOC, MSSP, or SIEM.

The 1Security REST API lets a SOC, MSSP, or SIEM pull your tenant's activity and detections on a schedule. It is read-only: a key can read the tenant's data and cannot change anything in 1Security or in your Microsoft 365 tenant.

ResourceEndpointWhat it is
Audit logs/logsNormalized M365 activity, enriched by 1Security
Monitoring alerts/monitoring-alertsAlerts raised by your monitoring policies
Security alerts/security-alertsMicrosoft Defender / Sentinel-sourced alerts

This page is the contract: endpoints, parameters, fields, and error codes. For how to wire it into a specific SIEM, see the SIEM integration guide.

Delivery is pull-based: you poll, we do not push. Outbound webhook delivery is planned - until it ships, the polling pattern in the integration guide is the supported approach.

Base URL

The API is served from the same deployment that runs your 1Security instance, under the /api/v1 prefix.

DeploymentBase URL
Cloud (SaaS)https://api.1security.ai/api/v1
BYOC / On-Premisehttps://<your-1security-host>/api/v1

In a BYOC or on-premise deployment the API stays inside your own network perimeter. Everything else on this page is identical across deployments.

All examples below use the SaaS base URL and assume the key is in an environment variable:

export ONESEC_API_KEY="1sec_live_…"

Authentication

Every request is authenticated with a per-tenant API key. A key is bound to exactly one tenant and grants read access to that tenant's data only.

Creating a key

In the dashboard, go to Settings → API Keys and choose Create API key. Key management is admin-only.

You choose a name, the scopes the key should carry, and optionally an expiry date. The full secret - 1sec_live_… - is displayed once, at creation. 1Security stores only a cryptographic hash of it, so it cannot be shown again or recovered by anyone, including support. Copy it straight into your SIEM's credential store.

Sending the key

Pass it as a bearer token (preferred) or in X-API-Key:

curl -H "Authorization: Bearer $ONESEC_API_KEY" \
  https://api.1security.ai/api/v1/ping
curl -H "X-API-Key: $ONESEC_API_KEY" \
  https://api.1security.ai/api/v1/ping

Start with /ping. It confirms the key is valid and shows which tenant and scopes it maps to, which rules out the most common setup mistakes before you build a connector around it.

Scopes

Each key carries one or more read scopes. A request to an endpoint whose scope the key lacks returns 403 - grant only what the integration needs.

Prop

Type

Rotating and revoking

Revocation takes effect immediately - the next request with that key returns 401. To rotate without downtime: create the replacement key, deploy it to the connector, confirm traffic on the new key in Settings → API Keys (each key shows when it was last used), then revoke the old one.

Treat an API key like a password. Anyone holding it can read the tenant's activity and alerts. Store it in a secret manager, never in a repository or a connector's plain-text configuration file.

Response format

Every successful list response uses the same envelope:

{
  "data": [
    /* … */
  ],
  "pagination": {
    "nextCursor": "eyJvIjo1MH0",
    "hasMore": true,
    "limit": 50
  }
}

Single-object endpoints (/ping, /security-alerts/{id}) return { "data": { … } } with no pagination block.

Fields are whitelisted per endpoint, so the shape is stable: new fields may be added over time, existing ones are not removed or renamed without notice.

Timestamps

All timestamps are UTC.

/logs and /security-alerts return full ISO-8601 (2026-06-05T09:12:44Z). /monitoring-alerts currently returns 2026-06-05 09:12:44 - the same UTC instant without the T separator or the Z designator. A future release unifies this on ISO-8601 across all endpoints, so parse defensively and treat values without a zone designator as UTC.

Pagination

List endpoints return at most limit items (default 50, max 1000) plus an opaque cursor. Pass the returned nextCursor back as ?cursor= to fetch the next page. When hasMore is false, nextCursor is null and you have reached the end.

Treat the cursor as meaningless - echo it back unchanged. Its encoding is an implementation detail and will change.

Page over a closed time window. Paging a live, open-ended result set is not safe: new events keep arriving at the head of the ordering while you page, which shifts rows between requests. Bound both ends of the window (discoveredFrom and discoveredTo on /logs, from and to on the alert endpoints) and the set stops changing underneath you while you drain it. The integration guide turns this into a concrete polling loop.

For a fully deterministic drain on /logs, add sort=discoveredAtAsc: that ordering is tie-broken by event id, so every row has exactly one position. On the alert endpoints, rows sharing an identical sort value have no guaranteed relative order, so keep windows narrow and deduplicate on id.

Rate limits

Keys are limited to 600 requests per minute, applied per key on a best-effort basis. Successful responses carry:

HeaderMeaning
X-RateLimit-LimitRequests allowed in the current window
X-RateLimit-RemainingRequests left in the current window
X-RateLimit-ResetWhen the window resets, in epoch seconds

Exceeding the limit returns 429 with a Retry-After header. Polling each endpoint once per minute with a large limit sits far inside the budget; the limit exists to blunt runaway loops, not to shape normal integration traffic.

Endpoints

GET /ping

Connection test. Returns the tenant and scopes the key maps to. Requires no particular scope - any valid key works.

curl -H "Authorization: Bearer $ONESEC_API_KEY" \
  https://api.1security.ai/api/v1/ping
{
  "data": {
    "tenantId": "01H…",
    "keyId": "01J…",
    "name": "Splunk prod",
    "scopes": ["logs:read", "monitoring-alerts:read", "security-alerts:read"]
  }
}

GET /logs

Normalized M365 activity events, enriched with the actor, resource, application, device, and location 1Security resolved for each one. Requires logs:read.

Two different times are recorded per event, and the difference matters when polling:

  • occurredAt - when the action happened in Microsoft 365.
  • discoveredAt - when 1Security ingested it. M365 can surface events well after the fact, so this is the one to poll on. An event that arrives late has an old occurredAt but a current discoveredAt.

Query parameters

Prop

Type

curl -H "Authorization: Bearer $ONESEC_API_KEY" \
  "https://api.1security.ai/api/v1/logs?severity=high,critical&limit=100"
{
  "data": [
    {
      "id": "01J…",
      "occurredAt": "2026-06-05T09:12:44Z",
      "discoveredAt": "2026-06-05T09:13:01Z",
      "action": "FileDownloaded",
      "description": "Downloaded Q3-forecast.xlsx",
      "severity": "high",
      "actorId": "01H…",
      "actorName": "jane@contoso.com",
      "actorType": "user",
      "actorIp": "20.42.0.0",
      "resourceId": "01H…",
      "resourceName": "Q3-forecast.xlsx",
      "resourceType": "file",
      "workload": "SharePoint",
      "sourceType": "azure",
      "sourceName": "Microsoft 365",
      "clientApp": "OneDrive Sync",
      "deviceId": "01H…",
      "deviceName": "LAPTOP-4471",
      "isManagedDevice": false,
      "applicationId": "01H…",
      "applicationClientId": "ab12…",
      "applicationDisplayName": "Microsoft SharePoint",
      "externalEventId": "…"
    }
  ],
  "pagination": { "nextCursor": "eyJvIjoxMDB9", "hasMore": true, "limit": 100 }
}

Response fields: id, occurredAt, discoveredAt, action, description, severity, actorId, actorName, actorType, actorIp, resourceId, resourceName, resourceType, workload, sourceType, sourceName, clientApp, deviceId, deviceName, applicationId, applicationClientId, applicationDisplayName, isManagedDevice, externalEventId.

GET /monitoring-alerts

Alerts raised by your monitoring policies. Requires monitoring-alerts:read.

Query parameters

Prop

Type

curl -H "Authorization: Bearer $ONESEC_API_KEY" \
  "https://api.1security.ai/api/v1/monitoring-alerts?severity=high&isResolved=false&limit=50"

Response fields: id, name, severity, status, isResolved, resourceType, resources, assignedUser, description, createdFrom, lastScan, resolvedAt, snoozedAt.

lastScan is when the alert was raised, and it is the same value that from and to filter on. Use it as the event time in your SIEM. Note that alerts change state after they are raised - see tracking alert state in the integration guide.

GET /security-alerts

Microsoft Defender / Sentinel-sourced alerts, linked to the users, groups, emails, and apps 1Security matched them to. Requires security-alerts:read.

Query parameters

Prop

Type

curl -H "Authorization: Bearer $ONESEC_API_KEY" \
  "https://api.1security.ai/api/v1/security-alerts?severity=high&status=new"

Response fields: id, title, description, severity, status, classification, category, threatDisplayName, firstActivityDateTime, isResolved, users, groups, emails, apps.

GET /security-alerts/{id}

Full detail for a single security alert. Requires security-alerts:read. Returns 404 if the id does not exist within your tenant.

Use this to enrich an alert already in your SIEM: forward the summary from the list endpoint, then fetch the detail on demand during triage rather than indexing the full payload for every alert.

curl -H "Authorization: Bearer $ONESEC_API_KEY" \
  https://api.1security.ai/api/v1/security-alerts/01J…

Response fields: everything from the list endpoint plus determination, assignedTo, alertWebUrl, incidentWebUrl, serviceSource, detectionSource, createdDateTime, lastUpdateDateTime, resolvedDateTime, lastActivityDateTime, recommendedActions, actorDisplayName, threatFamilyName, and rawData - the original provider payload, unmodified.

Errors

Errors use a consistent JSON shape and standard HTTP status codes:

{
  "error": {
    "code": "UNAUTHENTICATED",
    "message": "Invalid, expired, or revoked API key."
  }
}

Limits of the current API

Being explicit about what is not here yet, so you can design around it:

  • No push delivery. Webhook subscriptions are planned; today you poll.
  • No write access. Alerts cannot be acknowledged or resolved through the API. Bidirectional sync is planned.
  • One tenant per key. MSSPs managing several tenants need one key per tenant today. Organization-level keys are planned.
  • Three resources. Anomalies, remediation history, and entity lookups are not yet exposed.

Next

On this page