Ever been mid-incident, staring at a dashboard, wishing you could just grab the last hour of logs for a specific environment without opening a ticket or waiting on someone? That's exactly what the v2 Log API is built for.
It's a lightweight, read-only HTTP endpoint that returns log records for the PaaS environments your account is licensed for. Point a GET request at it, describe what you want — environment, service, time range, an optional search term — and get back a clean JSON envelope of matching records. It's designed for the real world: dashboards, incident-response tooling, and the quick ad-hoc scripts you reach for when something looks off.
In this post I'll walk you through how it works end to end — authentication, every parameter, the response shape, error handling, and a few copy-paste examples to get you moving.
Migrating from v1? If you already have a v1 client, read the Log API — Migration Guide (v1 → v2) instead — it covers the move step by step.
The 30-second overview
You issue an HTTP GET with query parameters, and you receive a JSON envelope containing matching log records. That's the whole model.
A couple of things worth knowing up front:
Authentication: guard your key
Every request carries your API key in the x-api-key header:
x-api-key: <your-api-key>
Your account team issues this key at onboarding. Treat it like a password — it grants read access to your log data.
Rotate it on a schedule you agree with your account team, or immediately if you suspect it's leaked. When a rotation happens, you get a new key and your existing key keeps working for 7 days by default. (The migration guide's “Key rotations after migration” section has the finer details.)
The endpoint
There's just one:
So a full request URL looks like:
https://log-api.alfrescocloud.com/v2/filter?<query-parameters>
One endpoint, one method. Everything you do here is a variation on that.
The query parameters, one by one
There are seven parameters. Only one is required — the rest have sensible defaults.
env — required
The PaaS environment whose logs you want. It must be one of the environments licensed to your account (for example customer-dev, customer-uat, customer-prod). Ask your account team for the exact env values that apply to you.
service — optional (default acs)
Selects which service's logs to return. Three fixed values:
Value | Returns logs from |
acs (default) | The content service — the main Alfresco repository and its content-handling components. |
search | The search service. |
transform | The content-transform service. |
Anything else → 400 service-invalid.
time_from — optional (default now - 1h)
The lower bound of your time window. Three formats accepted:
Unparseable → 400 time-invalid.
time_to — optional (default now)
The upper bound of your window. Same three formats as time_from.
sort — optional (default desc)
Orders returned records by timestamp:
Anything else → 400 sort-invalid.
limit — optional (default 10, max 1000)
Maximum number of records returned. Values above 1000 are clamped to 1000. A non-integer or a value ≤ 0 → 400 limit-invalid.
search_string — optional (no default)
Filters the response to records whose message body contains the given substring. It's a case-sensitive, plain-string match — not a regex. Max length 1024 characters.
Remember to URL-encode the value if it contains characters like +, &, #, or spaces. Over 1024 characters → 400 search-string-too-long.
What you get back
Successful responses (200 OK)
The body is a JSON envelope with a single top-level logs array. Each element is a log record:
{
"logs": [
{
"timestamp": "2026-08-04T09:12:33.184Z",
"level": "INFO",
"message": "Request processed in 42ms",
"service": "acs-catalina"
}
]
}
Every field is copied straight from the source record and is null when the source omits it — so treat all four as nullable:
If nothing matches, logs comes back as [].
Error responses
Every documented error has the same shape:
{ "error": "<stable-code>" }
Those <stable-code> values are stable across releases — branch on them programmatically rather than parsing human-readable text.
HTTP | error code | Meaning |
400 | env-required | The env parameter is missing. |
400 | env-not-permitted | Your API key isn't licensed for the requested env. |
400 | service-invalid | The service value isn't acs / search / transform. |
400 | sort-invalid | The sort value isn't asc or desc. |
400 | limit-invalid | The limit value isn't a positive integer. |
400 | time-invalid | time_from or time_to couldn't be parsed. |
400 | search-string-too-long | search_string exceeds 1024 characters. |
401 | unauthorized | The x-api-key header is missing, unknown, revoked, or its rotation grace period has expired. |
403 | not-found | The path or method doesn't exist. GET /filter is the only supported request. |
429 | rate-limited | You exceeded your per-customer rate limit. Back off and retry. |
429 | quota-exceeded | You exhausted your quota for the current period. Retrying won't help until it resets. |
500 | internal-error | Something unexpected happened. Report it with the request timestamp. |
502 | upstream-error / upstream-unreachable | The backend log store errored or was unreachable. Transient — retry. |
504 | poll-budget-exceeded | The query exceeded the ~20s server budget. Narrow the window or add a search_string. |
Two things that trip people up:
Rate limits
Rate limiting applies where a rate-limit policy has been provisioned for your deployment. Where one is, your key is subject to a per-customer rate limit and a daily quota — both agreed with your account team at onboarding. Exceed either and you get 429 Too Many Requests, with the error code telling you which:
Where no policy is provisioned, neither 429 code is returned. Check with your account team if you're unsure which applies.
There's no Retry-After header — use exponential backoff with jitter instead: start around one second, double on each failure, and cap at a ceiling that suits your workload.
Examples to get you started
GET https://log-api.alfrescocloud.com/v2/filter?env=customer-prod
x-api-key: <your-api-key>
Uses service=acs, time_from=now - 1h, time_to=now, sort=desc, limit=10.
GET https://log-api.alfrescocloud.com/v2/filter?env=customer-prod&service=search
&time_from=2026-08-04T09:00:00Z&time_to=2026-08-04T10:00:00Z&limit=500
x-api-key: <your-api-key>
Up to 500 search-service records between 09:00 and 10:00 UTC on 2026-08-04.
GET https://log-api.alfrescocloud.com/v2/filter?env=customer-prod
&search_string=Timeout&limit=200&time_from=now%20-%206h
x-api-key: <your-api-key>
Up to 200 ACS records from the last 6 hours whose message contains Timeout. Note the URL-encoded spaces (%20) in time_from.
GET https://log-api.alfrescocloud.com/v2/filter?env=customer-prod&sort=asc
&time_from=now%20-%202h&limit=1000
x-api-key: <your-api-key>
Up to 1000 ACS records from the last 2 hours, oldest first — handy when you're correlating a sequence of events.
A few tips from experience
Need a hand?
Questions, unexpected errors, or a request for higher rate limits? Reach out to your account team or file a support ticket. Include the request timestamp, the full request URL (redact the API key), and the observed response so we can reproduce it quickly.
Happy log-hunting — and let us know in the comments how you're wiring the Log API into your own tooling. 👇
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.