External Services and ERP Connectors

The previous chapter covered how others call AI GO. This one covers the opposite direction — how AI GO calls out.

There are two mechanisms with different purposes:

MechanismPurposeConfigured in
External services (egress)Custom Apps calling arbitrary external APIsThe Builder's External Services tab
External data connectorsColumn-level synchronization with existing ERPs and databasesDashboard → Data Center → External Data

1. External services: an application's outbound channel

Custom Apps cannot reach the internet freely. Every outbound call must go through an authorized external service. That is deliberate — it prevents applications from sending enterprise data somewhere nobody approved.

Where to configure

The Builder's External Services tab is the only entry point. What you configure there is which external services this application may call.

Domain allowlist

Authorization is granted per domain: authorize api.logistics.example.com and the application can only reach paths under that domain. Unauthorized domains are unreachable regardless of what the code says.

Authentication: credentials belong to the application

The gateway does domain validation only — it does not hold credentials, and it neither injects nor strips the Authorization header. Credentials for external APIs live in the application's App Secrets (ctx.secrets), and the server action assembles its own authentication header at call time:

def execute(ctx):
    resp = ctx.http.call('logistics', '/track',
                         method='POST',
                         headers={'Authorization': f"Bearer {ctx.secrets.get('LOGISTICS_KEY')}"},
                         body={'no': ctx.params['tracking_no']})

If the external API returns 401, the application's own credentials are at fault (a malformed header, an expired key) — check App Secrets and the code; no change to the external service configuration is needed.

Using it in code

def execute(ctx):
    resp = ctx.http.call('logistics', '/track',
                         method='POST',
                         body={'no': ctx.params['tracking_no']})

    if resp['status'] != 200:
        # data carries error_type / error / fix
        return ctx.response.json({'error': resp['data'].get('fix')})

    ctx.response.json(resp['data'])

The first argument is the service identifier, not a full URL; the path is appended to that service's base URL.

Actionable error messages

When an outbound call fails, data carries three fields:

FieldContents
error_typeClassification (unauthorized, timeout, bad credentials, domain not allowlisted…)
errorTechnical message
fixA single sentence you can relay to the user as a remedy

fix exists by design — it lets an application show "how to fix this" to the operator instead of a technical stack trace. The Builder UI and the AI development assistant also read it when helping you debug.

Symptoms of a missing authorization

When code calls a service that has no matching external-service entry, or one not authorized for this application, the gateway blocks it at runtime and the response's fix field says what's missing. The platform neither validates nor stores credentials — a missing key only surfaces as a 401 when the external API is actually called, and is the application's error to handle.

Fetching arbitrary URLs

Besides named services, ctx.http.fetch can retrieve arbitrary public URLs (for example a public exchange rate or notice page). Security restrictions remain fully in force — it cannot be used to reach internal network addresses.


2. External data connectors: synchronizing with existing systems

Entry point: Dashboard → Data Center → External Data. Requires system.admin.

Unlike external services, this mechanism handles structured data synchronization — mapping an existing ERP or database to AI GO's data model and syncing on a schedule.

Supported sources

  • Generic RESTful APIs
  • Generic external databases (PostgreSQL, MySQL, and others)
  • Preset connection profiles for mainstream ERP systems

After creating a data source you can test the connection to verify reachability and health.

Field mapping

Once connected, external columns must be mapped to AI GO's data model.

Mapping templates: common ERP systems ship preset templates (customer master, product master, and so on) that a wizard can apply.

AI mapping suggestions: for custom tables or non-standard systems, AI analyzes semantic similarity between external column names and types and AI GO's columns, proposing the best correspondence. This substantially reduces column-by-column configuration.

Direction and logs

DirectionNotes
External → AI GORead-only pull
AI GO → externalWrite back
BidirectionalBoth ways

Sync logs record each run's timestamp, row counts, status, and error messages for tracking consistency and troubleshooting.


3. Which one to use

SituationUse
App calls an SMS API to send a codeExternal service
App queries logistics statusExternal service
App calls your own model APIExternal service + App Secrets
Sync an existing ERP's customer master inExternal data connector
Keep order data consistent across two systemsExternal data connector
One-time migration of legacy dataData import (Chapter 6)

Rule of thumb: single calls use external services, ongoing sync uses connectors, one-time migration uses import.


4. The other direction: letting external systems push to you

If the external system supports event push, don't poll — use a webhook and let it call you.

Enabling webhooks on a Custom App action gives you a public endpoint:

POST https://{app subdomain}/webhook/{action_name}

Always verify the caller inside the action (for example by comparing a signature with ctx.crypto.hmac_sign). See Chapter 9.


5. Security boundary summary

  • Applications can only call explicitly authorized domains
  • Outbound credentials live in App Secrets, never in application source
  • Internal network addresses are protected and cannot be reached by fetching arbitrary URLs
  • Calling external services requires the http scope, which is high-risk — granting it requires the owner's password
  • Every outbound call is audited