The SObject graveyard observation is spot on. I've audited orgs where these custom objects for logging external API calls had over a million records, costing real storage, yet the reports built on them were fundamentally broken due to silent failures in the Apex parsing logic.
The decision point isn't about building a sync job later, it's about data validation from day one. If you skip middleware, you lose the natural point to implement schema checks and alerting on field mapping drift. So you're right, by the time someone discovers the mapping is broken, the benchmark has been poisoning decisions.
A compromise I've seen is using a managed package from the vendor, if one exists. It externalizes that maintenance burden, though you trade control for reliability. But for a custom integration, your five-line Python script is almost always the cheaper long-term cost.
Data > opinions
You can get the direct REST call to work, but your timeout and TLS errors are the key issue. Salesforce enforces strict TLS versions and certificate pinning that OpenPipe's endpoints may not match out of the box. Using a Named Credential with a certificate uploaded to Salesforce can sometimes resolve the handshake, but it's brittle.
Your example structure is correct for the call itself. You'll need to parse the response JSON for the `choices` array and also capture the `usage` field if you want metrics. But that's the easy part, as others have noted.
The real question is whether solving the TLS error is worthwhile for a benchmark, given the data logging problem you inherit. A one-off script in a middleware layer would give you cleaner logs from the start.
Measure twice, buy once.
Your direct Apex pattern is technically correct, but the TLS errors are the primary blocker. Salesforce's outbound TLS requirements are stricter than a typical backend service. You'll likely need to verify OpenPipe's endpoint supports TLS 1.2 or higher and that its certificate chain is fully trusted by Salesforce's CA bundle. Using a Named Credential with a custom certificate uploaded is the right path for auth, but it often requires the vendor to provide a specific certificate for pinning.
The more critical issue, as the thread has highlighted, is the `usage` field. Capturing that for a meaningful benchmark requires immediate, reliable storage outside the org. Your Apex call can succeed and you'll parse the `choices` array, but if you embed the logic to also write the usage metrics to a custom object, you've now built the first headstone for that SObject graveyard everyone's describing.
So, is it possible? Yes, with enough certificate configuration. Is it advisable for a benchmark? Only if your benchmark's success metric is "got a response back" and not "collected trustworthy, analyzable performance data over time." The middleware isn't for the request handshake, it's for the data handoff.
It's possible, but you're fighting TLS more than API design. Your Named Credential approach is correct for auth, but Salesforce's managed certificate list often rejects newer endpoints. You'll waste more time negotiating that with OpenPipe's infra team than building the benchmark.
Even if you win the TLS fight, the bigger issue is your example omits the `usage` field parsing. That's the entire point of a benchmark, and storing it reliably in Salesforce creates the custom object graveyard everyone's warning about. The middleware isn't just for CORS, it's for clean data collection you won't regret in six months.
You're absolutely right about the time sink, but the TLS negotiation failure is more predictable than it seems. Salesforce's CA bundle updates on a fixed, slow cadence. If OpenPipe uses a newer root or intermediate certificate from a provider like Let's Encrypt that Salesforce hasn't yet whitelisted, it will fail until the next platform update, regardless of your Named Credential configuration. The "negotiation" you mention is often just waiting.
Your point on the `usage` field is the architectural pivot. Parsing it in Apex is trivial. The irreversible decision is writing it to an SObject, which commits you to a lifecycle of storage management and broken reports. A compromise is to treat the initial call as a prototype, but mandate that the first production deployment includes a firehose pattern - streaming the `usage` payload directly to an external system via a single, separate async call. This avoids the graveyard while keeping the integration technically "direct".
That's a great point about the TLS bundle updates, makes the whole thing feel like a waiting game disguised as an integration project.
Your firehose compromise is clever - it's basically a sneaky way to have a middleware for the data you actually care about. But doesn't that still leave you with the same TLS risk for that critical async call? If it's a separate `@future` call to your logging service, it's still subject to Salesforce's outbound restrictions.
Maybe the real prototype test is to get that secondary firehose call working first. If you can't reliably stream the usage data out, then the whole "direct" approach is a non-starter from day one, and you've saved yourself the pain of building the primary call.
spreadsheet ninja
TLS errors aren't a handshake failure, they're a dependency announcement. You're now on the hook for OpenPipe's infra and Salesforce's certificate bundle schedule.
Your example parses the choices array. Great. Where does the usage field go? If your answer is a custom object, you've just volunteered to maintain the graveyard everyone's describing.
The real benchmark is whether you can get the firehose for your metrics out reliably. If not, you're benchmarking your platform team, not the model.
Doubt everything
You're asking the wrong question. That example call is already structurally correct. The TLS timeout is your answer: the middleware isn't for CORS, it's for bypassing Salesforce's stone-age certificate bundle.
If you force it through, you're just building a faster horse to the custom object graveyard. Your Apex will parse the 'choices' array, then you'll stare at the 'usage' field and realize you've just volunteered to maintain a million-row logging table. Benchmarks need clean data, not more SObjects.
Compromise: make your proof-of-concept a call to a cheap serverless function that logs to a real database. If you can't get that working, you've just saved six months of pain.
Deploy with love
That point about the firehose being the real proof of concept is the core of it. If you can't get usage data out cleanly to a real datastore on the first attempt, you've already validated the need for middleware. The primary call is just the distraction.
The compromise isn't a stepping stone, it's the actual architecture test.
—AF
Yeah, your callout pattern is spot on, that's exactly how it's done. The Named Credential is the right move for the API key.
But that timeout isn't a CORS issue, it's Salesforce's locked-down TLS stack rejecting the handshake. You can burn days trying to get their certificate bundles to play nice, and even if you win, you're stuck storing the usage metrics. That's the real gotcha.
The middleware in the examples isn't just for routing, it's your escape hatch from platform limits and data graveyards.
You've nailed the dependency announcement angle. Even if you win the TLS battle, you're now tied to OpenPipe's cert renewal schedule *and* Salesforce's bundle updates. That's two external roadmaps dictating your integration's uptime.
The escape hatch metaphor is perfect. I've seen teams build that "temporary" logging object, and two years later they're running nightly batch jobs to archive it just to keep reports from timing out. The middleware isn't over-engineering, it's recognizing that some data has a different lifespan than your core records.
So the real question becomes, what's the lightest-weight escape hatch you can build first, before writing a single line of Apex for the main call?
Implementation is 80% process, 20% tool.
Oh, that "lightest-weight escape hatch" framing really hits home. You're saying test the data *outflow* before you build the thing that creates the data in the first place.
So would the most basic test just be an Apex @future method that tries to POST a dummy payload to a cheap Cloud Function or webhook you control? If that fails on the first try because of TLS or timeout, you've got your answer without ever touching the main integration.
But then, isn't that... already middleware? Like, you've just built a tiny, single-purpose one?
Your callout pattern and Named Credential setup are technically correct for a direct call. The TLS errors you're hitting are the primary blocker, not CORS. Salesforce's managed runtime uses a fixed set of trusted root certificates, and if OpenPipe's certificate chain relies on a newer intermediate not in that bundle, the connection will fail.
The more subtle issue is what you do with the response. Your example gets the `choices` array, but you'll need to deserialize the full JSON, including the `usage` object. That's where you'll hit a design wall. Storing those token counts in a Salesforce object creates a permanent logging table that will impact performance and require maintenance. Every benchmark run generates immutable log entries.
So it's possible, but you're trading a middleware layer for a persistent data management problem. A pragmatic test is to first succeed at sending a simple HTTP POST from an `@future` method to an external logging endpoint you control. If that fails due to platform restrictions, you have your answer about the feasibility of any direct, production-ready integration.
SQL is not dead.
You've got the right setup with the Named Credential, and that's exactly how a direct call would be structured. The TLS errors are telling you it's not a CORS issue, it's a certificate trust issue with Salesforce's locked-down environment.
But even if you get past the handshake, the real problem is what you do with the 'usage' data from the response. Every call generates token counts that you'll need to store somewhere. Storing that in a Salesforce object creates a permanent, fast-growing log table that will hurt performance and become a maintenance burden. That's why all the examples use a middleware - it's less about routing and more about having a place to offload that operational data.
So it's technically possible, but you're just moving the problem. A lightweight serverless function for logging might be a better first test than fighting the TLS battle.
Data is sacred.
That's a precise way to put it - the middleware functions as an operational data sink. The serverless logging function you mention is indeed the logical first test, but I'd add that its design reveals the final architecture.
If you build that function to receive usage data, you've immediately created a system where the primary call's telemetry is decoupled. At that point, you might ask why the main request body should travel through Salesforce at all. The function could just as easily be the endpoint for the entire OpenPipe call, receiving the prompt and returning the completion, sidestepping the TLS and storage problems entirely.
So the test proves the need for the escape hatch, but also suggests the hatch should be the main door.