- The pair travels in the JSON body, not a header. Every request carries
{"auth": {"api_key": ..., "api_secret": ...}}. The plugin adds that block itself and never logs it, and it keeps no request body on an error, because the body holds the secret. - A call needs
waitor acallback_url. Withwait: truethe connection stays open and the answer carries the result. With acallback_urlKraken answers at once with only the jobid(nosuccessfield) and posts the result, carrying the sameid, later. A request with neither is refused, and the plugin rejects it before the call. - Quota is measured in bytes.
account.statusreturnsquota_total,quota_usedandquota_remainingin bytes, not in images, so divide by 1048576 for mebibytes. - A one-file answer is flat. With
wait: true,file_name,kraked_urland the sizes sit at the top level of the answer. Only a multi-size resize fillsresults, one entry per size, and there one entry can saysuccess: falsewith amessagewhile the top-levelsuccessis true. resizeneeds astrategy. Kraken refuses a resize without one, and the plugin rejects it before the call.squaretakes asize; the others takewidthand/orheight.fitcrops to fill the box;fillkeeps the aspect ratio and pads withbackground.- Lossless is the default. Leave out
lossy, or set it tofalse, for lossless;lossy: trueand an optionalqualitytrade some fidelity for size. - A 200 with
success: falseis a failure. Kraken also refuses a whole request that way, such as an unsupported format, and the plugin throws rather than returning a result with every field missing. kraked_urlis temporary. Kraken serves an optimized file fromdl.kraken.iofor a limited time, so a caller that needs to keep it should download it.- Nothing is replayed. Every call is a POST that spends quota, so a 5xx, a dropped connection or a timeout is never retried: the image may already have been fetched and billed.
- The upload route takes base64. A tool call carries text, so
upload.optimizetakes the file as a base64 string (adata:URL works too), decodes it, and sends it to Kraken as the multipart file part beside the JSON options, which is the form/v1/uploadaccepts. - No webhooks are handled. A
callback_urlis where Kraken posts a result, and it is your endpoint to run, not this plugin’s.
- 3 typed API operations
Setup
1
Install
2
Add the plugin
corsair.ts
multiTenancy: true, scope calls with corsair.withTenant(id). See Quick start for KEK + Hub keys, and Multi-tenancy for account isolation.3
Choose authentication
- API Key (Recommended)
Store the Kraken.io API key before the first call: More: API Key
pnpm corsair setup --plugin=krakenio --tenant=acme api_key=<your-key> (leave out --tenant without multiTenancy), or pass it as key in the plugin options. With Hub, each tenant enters their own key on the connect page. See API key auth.4
Connect a tenant
Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see Connect / OAuth.
Example API calls
Read the plan and remaining quotaWhat’s next
API reference
Every
krakenio.api.* operation with input and output types.Connect / OAuth
createLink, Hub delivery, and tenant connect flows.
Use with agents
Expose this plugin’s operations as MCP tools.