Hedra Log drains API
Stream signed job lifecycle logs to HTTPS destinations. **Why the last batch failed.** `last_error` is the same error envelope a failed job returns from `GET /jobs/{job_id}`, not a free-text diagnostic. It is null until a batch fails and is cleared again on the next success. Its `code` comes from the one error vocabulary this API uses, narrowed for drain delivery to this set: | `code` | Means | | --- | --- | | `DEADLINE_EXCEEDED` | Your destination did not respond before the delivery timeout. | | `UNAVAILABLE` | Your destination could not be reached (DNS, TLS, or connection failure) or answered `5xx` — or redirected, which is never followed. | | `RESOURCE_EXHAUSTED` | Your destination answered `429`. | | `UNAUTHORIZED` | Your destination answered `401`. | | `PERMISSION_DENIED` | Your destination answered `403`. | | `NOT_FOUND` | Your destination answered `404`. | | `INVALID_ARGUMENT` | Your destination answered some other `4xx`. | | `FAILED_PRECONDITION` | The URL is not a permitted log drain target — it resolves to a blocked address range. Fix the URL; retrying will not help. | | `INTERNAL` | Hedra could not prepare the batch. | | `UNKNOWN` | No classification is available, including for drains that last failed before this field became structured. | `retryable` describes the condition, not what Hedra did: every failed batch is requeued until the drain auto-disables, so it answers whether fixing the destination and re-enabling is likely to help. The `message` is a fixed summary — your destination's URL, headers, credentials, and response body are never echoed back, so treat your own logs, not this field, as the record of what your destination returned. `disabled_reason` answers a different question and stays its own small vocabulary: `consecutive_failures` when five batches in a row failed, `disabled_by_user` when you turned the drain off.