Making errors actually useful
Why Postproxy stopped translating platform errors and started propagating them raw, with hints when they need one.
We wanted errors in Postproxy to be genuinely useful, and it took us a few tries to get there.
A working post is boring. It goes out, you see it on the platform, you move on. A failed post is where you actually need the API to help. That’s where someone is reading the response at 11pm trying to figure out what went wrong, or where an automated workflow has to decide whether to retry, alert a human, or drop the job. If the error isn’t good, everything downstream gets harder. In that sense, errors matter more than successes — the successful case takes care of itself, and the failed one is where the API either helps you or doesn’t.
The first attempt was to map every platform error to our own error set. It sounded clean on paper — one vocabulary across Instagram, LinkedIn, TikTok, everything. In practice it fell apart quickly. Instagram alone has a surprising amount of nuanced errors, and trying to squeeze all of that into our own categories meant throwing away detail that people actually needed. Every time a platform added a new sub-code we were behind. Developers ended up with a tidy label that told them less than the original message.
So we tried something else: propagate errors mostly as they were, with some rewording to make them easier to read. That was better, but still not great. Sometimes rewording helped, sometimes it quietly changed the meaning. And it didn’t fix the real problem, which is that some platform errors are just confusing on their own, no matter how you phrase them.
What we actually wanted was something simple — errors that are descriptive and actionable at the same time. Descriptive means you see exactly what the platform said, codes and sub-codes and all. Actionable means you know what to do about it. The earlier approaches were pulling against each other: translating made errors less descriptive, leaving them raw made them less actionable.
The version we landed on just propagates everything as-is. Original message, code, sub-code, untouched. And if we recognize an error that’s vague or misleading, and we know what’s actually going on, we attach a hint next to it. The raw data is always there, so you can google it, paste it into an AI, or look it up in Instagram’s error code reference. The hint is ours, added only when it’s helpful.
Here’s the kind of example that made us want this. Instagram returns:
Only photo or video can be accepted as media type.
On a perfectly valid image. The message sounds like the file is the wrong kind of media, but in reality it often just means the image is too big. You can’t figure that out from the text. You have to already know. So we keep the error exactly as Instagram sent it, and add a short note pointing at the size issue. You get both — what the platform said, and what it probably means.
The new field is called error_details, available in the dashboard and in the API response. For the example above, the failed platform entry looks like this:
{ "platform": "instagram", "status": "failed", "error": "Instagram API Error: Only photo or video can be accepted as media type.", "error_details": { "platform_error_code": "9004", "platform_error_subcode": "2207052", "platform_error_message": "Only photo or video can be accepted as media type.", "postproxy_note": "Check that your file doesn't exceed 8 mb for image and 300 mb for video" }}The raw platform message is preserved in platform_error_message, the codes are there to look up, and postproxy_note is our addition — only present when we have something useful to say. Full shape is in the posts reference.
It’s not a big feature, but debugging a failed post is one of those moments where an API either earns trust or loses it. Hopefully this helps.
Postproxy
One API for every social platform
Publish to Instagram, X, LinkedIn, TikTok, YouTube and more with a single request. Free plan, no credit card required.