Skip to content

feat(connectors): callApi for metered connectors - #250

Open
ChenMachBase wants to merge 2 commits into
base44:mainfrom
ChenMachBase:connectors-money
Open

feat(connectors): callApi for metered connectors#250
ChenMachBase wants to merge 2 commits into
base44:mainfrom
ChenMachBase:connectors-money

Conversation

@ChenMachBase

Copy link
Copy Markdown
Contributor

Summary

Adds callApi / callWorkspaceApi / callCurrentAppUserApi for metered connectors — connectors backed by paid third-party APIs that charge Base44 per call.

For those connectors the OAuth token is deliberately unavailable to app code (getConnection and friends reject with a 403), because the Base44 proxy is the only place the calls we pay for can be counted. These three methods are the replacement, and each mirrors its getConnection counterpart so the identifier you already use carries over:

New method Replaces Identified by
callApi(integrationType, request) getConnection integration type
callWorkspaceApi(connectorId, request) getWorkspaceConnection connector ID
callCurrentAppUserApi(connectorId, request) getCurrentAppUserConnection connector ID
const res = await base44.asServiceRole.connectors.callApi('x', {
  method: 'POST',
  path: '/2/tweets',
  body: { text: 'Shipped!' },
});
// -> { success, status, data, headers, creditsCharged }

Two shape decisions worth reviewing

An upstream 4xx/5xx resolves, it does not throw. A provider error is a normal outcome of a call Base44 completed and billed, so it comes back as success: false with the provider's own status and data. Only Base44-side failures — no connection, credits exhausted, a rejected request — reject the promise. Tests pin both sides of that split.

query is always forwarded, never dropped. The server prices the merged query string, so an SDK that accepted the field and then discarded it would make the quoted price and the real request disagree. (This is the client-side half of a billing bypass caught during review of the backend change.)

Responses carry creditsCharged, and the module docs gain a "Metered connectors" section noting that cost can vary by two orders of magnitude between endpoints on the same connector — an expensive call inside a loop being the failure mode worth warning about.

Testing

  • 11 new unit tests in tests/unit/connectors-proxy.test.ts: route targeting per connector kind, payload normalization, snake_casecamelCase mapping, query forwarding, upstream-error-resolves vs Base44-error-rejects, and the metered 403 surfacing an actionable message.
  • Full suite green: 203 tests, plus tsc --noEmit, npm run test:types, and eslint src all clean.
  • Installed with npm ci (lockfile-exact).

Notes

  • No version bump. Publishing, and bumping the pinned npm:@base44/sdk@0.8.40 in the platform's builder prompts, is a separate release step — that pin touches several prompt files including system-prompt ones, so it wants its own change.
  • Backend counterpart: base44-dev/apper#19753. That PR ships inert (no connector is registered as metered yet), so nothing here is load-bearing until it is.
  • Opened from a fork because the author's account has read-only access to this repo.

ChenMachBase and others added 2 commits August 12, 2026 12:33
Some connectors are backed by paid third-party APIs that charge Base44 per call.
For those the OAuth token is not available to app code — getConnection and its
siblings reject with a 403 — because the Base44 proxy is the only place those
calls can be counted. Adds the three proxy methods that replace them:

- callApi(integrationType, request)          — shared platform connector
- callWorkspaceApi(connectorId, request)     — workspace-registered connector
- callCurrentAppUserApi(connectorId, request) — per-app-user connector

Each mirrors its getConnection counterpart, so the identifier you already use
carries over.

Two deliberate shape decisions:

- An upstream 4xx/5xx resolves with `success: false` and the provider's own
  `status`/`data` rather than throwing. It is a normal outcome of a call Base44
  completed and billed; only Base44-side failures (no connection, credits
  exhausted, a rejected request) reject.
- `query` is always sent, never dropped. The server prices the merged query
  string, so a client that accepted the field and then discarded it would make
  the quoted price and the real request disagree.

Responses carry `creditsCharged` so callers can see what a call actually cost,
and the module docs call out that cost varies sharply by endpoint — an expensive
call inside a loop is the failure mode worth warning about.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Drops callWorkspaceApi and callCurrentAppUserApi. They implied that
workspace-registered and app user connectors can be metered, and they can't: both
run on the workspace's *own* OAuth app, so the provider invoices the workspace
directly. Proxying them would have billed the customer credits on top of a vendor
bill they already pay.

Only a platform connector runs on Base44's OAuth app, so callApi is the only one
of the three that ever had something to meter. The backend's matching routes are
gone too (base44-dev/apper#19753).

The module docs now say which connectors this applies to and, more usefully, why
the other two don't — so the next person doesn't re-add the methods on the
assumption they were an oversight.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant