# Foundation SDK Reference For Agents

Canonical integration reference for apps that use `foundation-sdk`.

Last updated: 2026-06-29

## Install

```bash
npm install foundation-sdk
npm install aws-amplify
```

Use `aws-amplify` only for Cognito apps. For Auth0 apps, install `@auth0/auth0-spa-js` instead.

## Initialize

Cognito:

```ts
import { createFoundation } from 'foundation-sdk'
import { cognitoAuth } from 'foundation-sdk/cognito'

const foundation = await createFoundation({
  configUrl: import.meta.env.VITE_FOUNDATION_CONFIG_URL,
  tenantId: import.meta.env.VITE_FOUNDATION_TENANT_ID,
  appId: import.meta.env.VITE_FOUNDATION_APP_ID,
  baseUrl: import.meta.env.VITE_FOUNDATION_API_BASE_URL,
  auth: cognitoAuth
})
```

Auth0:

```ts
import { createFoundation } from 'foundation-sdk'
import { auth0Auth } from 'foundation-sdk/auth0'

const foundation = await createFoundation({
  configUrl: import.meta.env.VITE_FOUNDATION_CONFIG_URL,
  tenantId: import.meta.env.VITE_FOUNDATION_TENANT_ID,
  appId: import.meta.env.VITE_FOUNDATION_APP_ID,
  baseUrl: import.meta.env.VITE_FOUNDATION_API_BASE_URL,
  auth: auth0Auth
})
```

Production may omit identity values:

```ts
const foundation = await createFoundation({ auth: cognitoAuth })
```

`/foundation-env.json` overrides `configUrl`, `tenantId`, `appId`, and clears `baseUrl`.

## Critical Rules

1. Always await `createFoundation(...)`.
2. Initialize the SDK once and share it through app context/state.
3. Use exactly one auth provider entry point unless building separate variants.
4. Do not put private secrets in frontend code.
5. Set `window.__foundation = foundation` only when using `foundation-sdk/components`.
6. Treat `baseUrl` as dev-only.

## Auth

Available methods:

```ts
foundation.auth.user
foundation.auth.isAuthenticated
foundation.auth.getToken()
foundation.auth.login(options?)
foundation.auth.logout(options?)
foundation.auth.handleCallback(url?)
foundation.auth.signIn(email, password)
foundation.auth.signUp(email, password, metadata?)
foundation.auth.confirmSignUp(email, code)
foundation.auth.resendSignUpCode(email)
foundation.auth.forgotPassword(email)
foundation.auth.resetPassword(code, newPassword)
foundation.auth.onChange(callback)
```

Sign-in pattern:

```ts
const result = await foundation.auth.signIn(email, password)
if (result.isSignedIn) {
  router.push('/dashboard')
} else if (result.nextStep?.signInStep === 'CONFIRM_SIGN_UP') {
  router.push({ path: '/confirm', query: { email } })
}
```

Sign-up pattern:

```ts
const result = await foundation.auth.signUp(email, password, { name })
if (result.isSignUpComplete) {
  showCheckEmail()
} else if (result.nextStep?.signUpStep === 'CONFIRM_SIGN_UP') {
  showCodeConfirmation()
}
```

Call `foundation.auth.handleCallback()` on hosted-login callback routes. Subscribe with `foundation.auth.onChange()` or refresh auth state after login, logout, callback, and registration.

## Database

```ts
foundation.db.list<T>(entity, options?)
foundation.db.get<T>(entity, id)
foundation.db.create<T>(entity, data)
foundation.db.update<T>(entity, id, updates)
foundation.db.save<T>(entity, data)
foundation.db.delete(entity, id)
```

List options:

```ts
{
  filters?: Record<string, unknown>
  limit?: number
  cursor?: string
  orderBy?: string
  orderDir?: 'asc' | 'desc'
}
```

Paginated list:

```ts
let cursor: string | undefined
const all = []

do {
  const { items, nextCursor } = await foundation.db.list('projects', {
    limit: 50,
    cursor
  })
  all.push(...items)
  cursor = nextCursor
} while (cursor)
```

## Files

```ts
foundation.files.upload({ name, contentType, file, sha256 })
foundation.files.initiate({ name, contentType, contentLength, sha256, metadata? })
foundation.files.get(fileId)
foundation.files.delete(fileId)
foundation.files.list({ limit?, cursor? }?)
```

Compute SHA-256 before upload:

```ts
const result = await foundation.files.upload({
  name: file.name,
  contentType: file.type,
  file,
  sha256
})
```

Use `initiate` only when the app needs manual control of the signed upload.

## Integrations

```ts
foundation.integration.all()
foundation.integration.list()
foundation.integration.connections()
foundation.integration.status(source)
foundation.integration.connect(source)
foundation.integration.disconnect(source, configurationId)
```

Use `foundation.integration.all()` for catalog plus current connection state.

Use `foundation.integration.connect(source)`. If the result includes a `url`, open a popup or redirect and refresh connection status after completion. Also handle immediate success/configuration responses.

Use `disconnect(source, configurationId)` only after clear user confirmation.

## Account

```ts
foundation.account.get<TUser, TAccount>()
foundation.account.update(data)
foundation.account.usage()
foundation.account.resendVerification()
```

## OAuth Consent

For apps acting as OAuth authorization servers:

```ts
const client = await foundation.oauth.getClient(clientId)
const { code } = await foundation.oauth.authorizeConsent({
  client_id,
  redirect_uri,
  scope,
  state,
  code_challenge,
  code_challenge_method
})
```

Only call `authorizeConsent` after explicit user approval, then redirect back with `code` and `state`.

## Config

```ts
foundation.config.app
foundation.config.features
foundation.config.plans
foundation.config.theme
foundation.config.connectors
foundation.config.resources
foundation.config.auth
foundation.config.raw
```

Use backend config to hide unavailable UI and apply theme or plan-aware behavior.

## Logging

```ts
foundation.log.info(message, context?)
foundation.log.warn(message, context?)
foundation.log.error(message, context?)
foundation.log.event(eventName, data?)
```

Logging is fire-and-forget. Do not block UI on logging.

## Web Components

```ts
import 'foundation-sdk/components'
;(window as any).__foundation = foundation
```

```html
<foundation-connect integration-id="github-oauth"></foundation-connect>
```

Events: `success`, `error`, `close`.

For Vue, configure `isCustomElement` for `foundation-*` tags.
