You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You spent your own time for zammad between you the report was complete: one showed the documentation was wrong, the other posted what actually works so the next person wasn't stuck on it. That is considerably more than a bug report usually gives us. ❤️
It is now fixed in #171, and I'd like your read on it before it goes in.
You reported two things, and both turned out to be worth more than a doc patch.
The withToken one went deeper than stale docs. You both independently reached for ZammadClient::withToken(), which told us something: the documented API was the one people expect, and the real one was awkward enough that nobody guessed it. So rather than only correcting the examples, the entry point changed to match:
@Kicknride — the form you posted still works unchanged, so nothing you wrote needs touching. 'GuzzleClientFactory::withToken()' is now deprecated in favour of the above and will go in 4.0. For what it's worth, that you got there by asking an AI to read the source rather than by reading our docs is the clearest verdict on them we've had.
Digging into it surfaced the cause. The Authorization header was set as a Guzzle client default header — a Guzzle feature, not something PSR-18 offers — so anything that wanted authentication had to go through GuzzleClientFactory. That is why the guide asked you to hand-write an AuthMiddleware for Symfony's client. The credential now goes to the RequestHandler, which composes every request whatever the transport, so any PSR-18 client authenticates the same way: 07-custom-http-client.php is the entire recipe. In docs/custom-http-client.md that section went from 41 lines to 15 — the decorator is still documented, but only for the one case that genuinely needs it: credentials that rotate at runtime.
The CHANGELOG one was simply right. 3.0.0 still said "unreleased", 3.1.0 had no section at all. Both now carry their dates.
While we were in there we also found that the README documented performOnBehalfOf() and setOnBehalfOfUser() — removed in 3.0.0 — and that docs/ imported a namespace that does not exist. Same failure mode as your report, different page.
Two things we'd value your opinion on, and only these, because they are the two we cannot work out for ourselves:
Does ZammadClient::create($url, Auth::token($token)) read like what you were looking for, or does it still take a detour?
Was there anything else in the v3 docs that sent you the wrong way and that you worked around silently rather than reporting?
Thanks for pushing on this — especially for the "the documentation should be fixed anyway" line. That is the reason this got looked at properly instead of being closed with a snippet.
#171 is merged (db77427 on develop) and ships as 3.2.0 — not tagged yet.
@Kicknride — one line of my earlier comment is wrong: "GuzzleClientFactory::withToken() is now deprecated in favour of the above and will go in 4.0." That notice was withdrawn before the merge. The helpers stay supported and nothing is scheduled for removal, so your snippet is fine as it is — create() is a recommendation for new code, not a migration you owe us.
Links from my earlier comment point at the feature branch, so here they are on develop:
Activity
Kicknride commentedon Oct 9, 2026
Yes Claude IA saved me
use ZammadAPIClient\ZammadClient;
use ZammadAPIClient\Factory\GuzzleClientFactory;
$factory = GuzzleClientFactory::withToken('API_URL', 'TOKEN');
$client = new ZammadClient($factory);
kdambekalns commentedon Oct 9, 2026
Yes, finding the correct code is possible, but the documentation should be fixed anyway. 😇
derpixler commentedon Oct 12, 2026
Hi @kdambekalns, @Kicknride — thank you, both of you.
You spent your own time for zammad between you the report was complete: one showed the documentation was wrong, the other posted what actually works so the next person wasn't stuck on it. That is considerably more than a bug report usually gives us. ❤️
It is now fixed in #171, and I'd like your read on it before it goes in.
You reported two things, and both turned out to be worth more than a doc patch.
The
withTokenone went deeper than stale docs. You both independently reached forZammadClient::withToken(), which told us something: the documented API was the one people expect, and the real one was awkward enough that nobody guessed it. So rather than only correcting the examples, the entry point changed to match:@Kicknride — the form you posted still works unchanged, so nothing you wrote needs touching. 'GuzzleClientFactory::withToken()' is now deprecated in favour of the above and will go in 4.0. For what it's worth, that you got there by asking an AI to read the source rather than by reading our docs is the clearest verdict on them we've had.
(
00-connect.phpis the whole setup now)Digging into it surfaced the cause. The
Authorizationheader was set as a Guzzle client default header — a Guzzle feature, not something PSR-18 offers — so anything that wanted authentication had to go throughGuzzleClientFactory. That is why the guide asked you to hand-write anAuthMiddlewarefor Symfony's client. The credential now goes to theRequestHandler, which composes every request whatever the transport, so any PSR-18 client authenticates the same way:07-custom-http-client.phpis the entire recipe. Indocs/custom-http-client.mdthat section went from 41 lines to 15 — the decorator is still documented, but only for the one case that genuinely needs it: credentials that rotate at runtime.The CHANGELOG one was simply right. 3.0.0 still said "unreleased", 3.1.0 had no section at all. Both now carry their dates.
While we were in there we also found that the README documented
performOnBehalfOf()andsetOnBehalfOfUser()— removed in 3.0.0 — and that docs/ imported a namespace that does not exist. Same failure mode as your report, different page.Two things we'd value your opinion on, and only these, because they are the two we cannot work out for ourselves:
ZammadClient::create($url, Auth::token($token))read like what you were looking for, or does it still take a detour?Thanks for pushing on this — especially for the "the documentation should be fixed anyway" line. That is the reason this got looked at properly instead of being closed with a snippet.
kdambekalns commentedon Oct 13, 2026
Thanks for the kind words and the fix. That goes above and beyond in itself, great!
To answer your questions:
ZammadClient::create($url, Auth::token($token))is fine with me.Add Auth and ZammadClient::create(), fix outdated v3 docs (#168)
derpixler commentedon Oct 14, 2026
#171 is merged (db77427 on develop) and ships as 3.2.0 — not tagged yet.
@Kicknride — one line of my earlier comment is wrong: "
GuzzleClientFactory::withToken()is now deprecated in favour of the above and will go in 4.0." That notice was withdrawn before the merge. The helpers stay supported and nothing is scheduled for removal, so your snippet is fine as it is —create()is a recommendation for new code, not a migration you owe us.Links from my earlier comment point at the feature branch, so here they are on develop:
Thanks again, both of you.
Add Auth and ZammadClient::create(), fix outdated v3 docs (#168)
Add Auth and ZammadClient::create(), fix outdated v3 docs (#168)