Skip to main content
This guide connects a PostgreSQL or MySQL database to an agent so it can answer from live records on a call — for example “when’s my appointment?” — using a least-privilege user, data scoping, and a bound read query. Every step is one API call against https://builder.flowyte.com/api/v1.
Authenticate every request with a secret API key: Authorization: Bearer flowyte_sk_…. See Authentication to mint one. Below, KIND is postgres or mysql.

What you’ll wire up

ActionEndpointScope
Generate a scoped DB userGET /integrations/{kind}/sql/scriptsintegrations:read
Test the connectionPOST /integrations/{kind}/sql/testintegrations:write
ConnectPOST /integrations/{kind}/connectintegrations:write
Discover the schemaPOST /integrations/{kind}/discoverintegrations:write
Scope out sensitive dataPATCH /integrations/{kind}/scopingintegrations:write
Bind a read as a skillPOST /agents/{id}/integrations/{kind}/bindingsskills:write
PublishPOST /agents/{id}/publishagents:write
1

Create a least-privilege database user

Generate the setup SQL, then run it on your database as an admin. Never connect Flowyte with your admin credentials — create a scoped user instead.
curl "https://builder.flowyte.com/api/v1/integrations/postgres/sql/scripts?database=appdb" \
  -H "Authorization: Bearer $FLOWYTE_API_KEY"
# → { "data": { "readOnly": { "sql": "CREATE ROLE flowyte_ro …" }, "generatedPassword": "…" } }
For read-only lookups, run the readOnly script. Only add the scoped write script (pass ?tables=appointments,requests) if the agent needs to insert or update rows.
2

Test the credentials

Validate before you store anything. The check runs reachability, TLS, auth, a read probe, a read-only-session proof, and a latency verdict, and returns an overall ok.
curl -X POST https://builder.flowyte.com/api/v1/integrations/postgres/sql/test \
  -H "Authorization: Bearer $FLOWYTE_API_KEY" -H "Content-Type: application/json" \
  -d '{ "credentials": {
        "host": "db.example.com", "port": "5432", "database": "appdb",
        "user": "flowyte_ro", "password": "…", "sslmode": "verify-full"
      } }'
# → { "data": { "ok": true, "checks": [ … ] } }
sslmode must be require, verify-ca, or verify-full (disable is refused). A host that resolves to a private, loopback, or metadata address is refused too.
3

Connect

Pass the same credentials to the connect endpoint. They’re encrypted at rest and never returned.
curl -X POST https://builder.flowyte.com/api/v1/integrations/postgres/connect \
  -H "Authorization: Bearer $FLOWYTE_API_KEY" -H "Content-Type: application/json" \
  -d '{ "credentials": {
        "host": "db.example.com", "port": "5432", "database": "appdb",
        "user": "flowyte_ro", "password": "…", "sslmode": "verify-full"
      } }'
# → { "data": { "status": "connected" } }
4

Discover the schema, then scope out anything sensitive

Introspect the database, then block tables or columns the agent should never see — they vanish from the schema browser and are refused at bind time.
curl -X POST https://builder.flowyte.com/api/v1/integrations/postgres/discover \
  -H "Authorization: Bearer $FLOWYTE_API_KEY"

curl -X PATCH https://builder.flowyte.com/api/v1/integrations/postgres/scoping \
  -H "Authorization: Bearer $FLOWYTE_API_KEY" -H "Content-Type: application/json" \
  -d '{ "blockedColumns": { "customers": ["ssn", "card_last4"] } }'
5

Bind a lookup as a skill

Map a read onto a skill: pick the operation, map the caller’s input to its filter, and project the columns you want back. It compiles to a frozen, parameterized query — the agent supplies the parameter and never sees raw SQL.
curl -X POST https://builder.flowyte.com/api/v1/agents/$AGENT_ID/integrations/postgres/bindings \
  -H "Authorization: Bearer $FLOWYTE_API_KEY" -H "Content-Type: application/json" \
  -d '{
        "toolName": "Look up an appointment",
        "description": "Find the caller'\''s appointment by phone and read back the time and status.",
        "operation": "appointments.read",
        "inputs": [ { "param": "caller_phone", "arg": "phone", "required": true } ],
        "projection": [
          { "path": ["appointment", "starts_at"], "leaf": "appointment_time" },
          { "path": ["appointment", "status"],    "leaf": "appointment_status" }
        ],
        "enabled": true
      }'
Don’t want to hand-map? POST /agents/{id}/integrations/postgres/bindings/auto takes a plain-language goal (“look up the caller’s next appointment by phone”) and the AI assistant proposes the binding, saved as a draft to review.
6

Publish and test

Binding edits the draft. Publish so live callers get real data, then try it in the simulator.
curl -X POST https://builder.flowyte.com/api/v1/agents/$AGENT_ID/publish \
  -H "Authorization: Bearer $FLOWYTE_API_KEY"

curl -N -X POST https://builder.flowyte.com/api/v1/agents/$AGENT_ID/simulate \
  -H "Authorization: Bearer $FLOWYTE_API_KEY" -H "Content-Type: application/json" \
  -d '{ "message": "Hi, can you tell me when my appointment is?", "draftMode": false }'

Safety model

  • Least privilege — you connect a scoped user, not an admin. Reads are read-only; writes are limited to the tables you granted.
  • Data scoping — blocked tables and columns never reach the schema browser, the AI assistant, or a binding.
  • Frozen queries — a binding compiles to one parameterized statement. The agent passes parameters; it can’t run arbitrary SQL, and writes land disabled until you review them.
See the SQL database connector for the full endpoint reference.