---
title: Check recent event ingestion with an ingestion API key
description: Checks whether Amplitude received any events for the project associated with the supplied ingestion API key during the preceding eight hours. observed means…
product: general
token_estimate: 2406
---
# Check recent event ingestion with an ingestion API key

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

## Check recent event ingestion with an ingestion API key

**POST** `/v1/events/check-recent-ingestion`

Full URL: `https://developer-api.amplitude.com/v1/events/check-recent-ingestion`

**Servers:**
- Production: `https://developer-api.amplitude.com/v1/events/check-recent-ingestion`
- Staging: `https://developer-api.stag2.amplitude.com/v1/events/check-recent-ingestion`

Check recent event ingestion with an ingestion API key

Checks whether Amplitude received any events for the project associated
with the supplied ingestion API key during the preceding eight hours.

`observed` means at least one event was received in the evaluated window.
`not_observed` means no events were received. `inconclusive` means no events
were found, but the available data could not confirm their absence. Use the
returned window when reporting or comparing results.

The window uses server upload time: when Amplitude received each event,
rather than the event time supplied by the sender.

Provide `polling_timeout_seconds` to request server polling guidance.
While another check is advised, successful responses include
`poll_after_seconds`; its omission means clients should stop polling.

## Body (application/json)

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| api_key | string | Yes | — | Ingestion API key for the Amplitude project to check. Constraints: pattern: \S |
| polling_timeout_seconds | integer | No | — | Maximum polling window requested by the caller. Clients should complete the initial check even if it exceeds this window and use the window only to limit subsequent polls. Its presence requests polling guidance; it is not an HTTP request timeout, and each HTTP request performs one check. Constraints: min: 1, max: 120 |

## Response (application/json)

**200** — Recent event ingestion status for the evaluated window.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| data | object | Yes | — | — |
| data.status | string | Yes | — | `observed` when at least one event was received; `not_observed` when none were received; `inconclusive` when none were found but their absence could not be confirmed. Allowed values: observed, not_observed, inconclusive |
| data.poll_after_seconds | integer | No | — | Minimum seconds to wait before the next ingestion check. Returned only when polling was requested and another check is advised. Its omission means the server does not advise another check. Constraints: min: 1 |
| data.window | object | Yes | — | — |
| data.window.lookback_hours | integer | Yes | — | Number of hours evaluated. |
| data.window.start | string | Yes | — | Start of the evaluated window. Constraints: format: date-time |
| data.window.end | string | Yes | — | End of the evaluated window. Constraints: format: date-time |
| data.window.basis | string | Yes | — | The window is based on when Amplitude received each event. |

```json
{
  "data": {
    "status": "observed",
    "window": {
      "lookback_hours": 8,
      "start": "2026-09-03T09:00:00Z",
      "end": "2026-09-03T17:00:00Z",
      "basis": "server_upload_time"
    }
  }
}
```

**400**

**401** — The supplied API key is invalid.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| type | string | Yes | — | Constraints: format: uri |
| title | string | Yes | — | — |
| status | integer | Yes | — | Constraints: min: 400, max: 599 |
| detail | string | No | — | Constraints: nullable |
| instance | string | No | — | Constraints: format: uri, nullable |
| error_code | string | Yes | — | — |
| retryable | boolean | Yes | — | — |
| retry_after_seconds | integer | No | — | Constraints: nullable, min: 0 |
| validation_errors | object[] | No | — | Constraints: nullable |

```json
{
  "type": "https://developer-api.amplitude.com/problems/invalid-api-key",
  "title": "The supplied API key is invalid.",
  "status": 401,
  "detail": "The supplied API key is invalid.",
  "error_code": "invalid_api_key",
  "retryable": false
}
```

**403** — The endpoint is unavailable.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| type | string | Yes | — | Constraints: format: uri |
| title | string | Yes | — | — |
| status | integer | Yes | — | Constraints: min: 400, max: 599 |
| detail | string | No | — | Constraints: nullable |
| instance | string | No | — | Constraints: format: uri, nullable |
| error_code | string | Yes | — | — |
| retryable | boolean | Yes | — | — |
| retry_after_seconds | integer | No | — | Constraints: nullable, min: 0 |
| validation_errors | object[] | No | — | Constraints: nullable |

```json
{
  "type": "https://developer-api.amplitude.com/problems/operation-not-enabled",
  "title": "The endpoint is unavailable.",
  "status": 403,
  "detail": "This endpoint is unavailable.",
  "error_code": "operation_not_enabled",
  "retryable": false
}
```

**429**

**500**

**502** — The ingestion status could not be determined. Retryable responses use
`unreliable_dataset_response` or `upstream_error` as the `error_code`.


| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| type | string | Yes | — | Constraints: format: uri |
| title | string | Yes | — | — |
| status | integer | Yes | — | Constraints: min: 400, max: 599 |
| detail | string | No | — | Constraints: nullable |
| instance | string | No | — | Constraints: format: uri, nullable |
| error_code | string | Yes | — | — |
| retryable | boolean | Yes | — | — |
| retry_after_seconds | integer | No | — | Constraints: nullable, min: 0 |
| validation_errors | object[] | No | — | Constraints: nullable |

```json
{
  "type": "https://example.com",
  "title": "The ingestion status could not be determined. Retryable responses use\n`unreliable_dataset_response` or `upstream_error` as the `error_code`.\n",
  "status": 502,
  "detail": "string",
  "instance": "https://example.com",
  "error_code": "string",
  "retryable": true,
  "retry_after_seconds": 0,
  "validation_errors": [
    {
      "field": "string",
      "message": "string",
      "code": "string"
    }
  ]
}
```

**503** — Endpoint not available.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| type | string | Yes | — | Constraints: format: uri |
| title | string | Yes | — | — |
| status | integer | Yes | — | Constraints: min: 400, max: 599 |
| detail | string | No | — | Constraints: nullable |
| instance | string | No | — | Constraints: format: uri, nullable |
| error_code | string | Yes | — | — |
| retryable | boolean | Yes | — | — |
| retry_after_seconds | integer | No | — | Constraints: nullable, min: 0 |
| validation_errors | object[] | No | — | Constraints: nullable |

```json
{
  "type": "https://developer-api.amplitude.com/problems/operation-availability-unavailable",
  "title": "Endpoint not available.",
  "status": 503,
  "detail": "This endpoint is not available.",
  "error_code": "operation_availability_unavailable",
  "retryable": true
}
```

## Code samples

### cURL

```bash
curl -X POST "https://developer-api.amplitude.com/v1/events/check-recent-ingestion" \
  -H "Content-Type: application/json" \
  -H "Authorization: YOUR_API_KEY"
```

### Python

```python
import requests

response = requests.post(
    "https://developer-api.amplitude.com/v1/events/check-recent-ingestion",
    headers={
        "Content-Type": "application/json",
        "Authorization": "YOUR_API_KEY"
    }
)
data = response.json()
```

### JavaScript

```javascript
const response = await fetch("https://developer-api.amplitude.com/v1/events/check-recent-ingestion", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "YOUR_API_KEY"
  }
});
const data = await response.json();
```

### PHP

```php
<?php
$ch = curl_init("https://developer-api.amplitude.com/v1/events/check-recent-ingestion");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json",
    "Authorization: YOUR_API_KEY"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
```

### Go

```go
package main

import (
  "bytes"
  "net/http"
)

func main() {
req, _ := http.NewRequest("POST", "https://developer-api.amplitude.com/v1/events/check-recent-ingestion", nil)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "YOUR_API_KEY")
  client := &http.Client{}
  resp, _ := client.Do(req)
  defer resp.Body.Close()
}
```

### Java

```java
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://developer-api.amplitude.com/v1/events/check-recent-ingestion"))
      .method("POST", HttpRequest.BodyPublishers.noBody())
.header("Content-Type", "application/json")
      .header("Authorization", "YOUR_API_KEY")
      .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
```

### Ruby

```ruby
require "net/http"
require "json"

uri = URI("https://developer-api.amplitude.com/v1/events/check-recent-ingestion")
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "YOUR_API_KEY"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end
```

