# Generate an app schema

> Read the tables of a connection and the columns of the tables named, so a sync can be built from exact table and column names. The credentials are read from the connection, never sent. Readable with a read-only key.

Source: https://docs.stacksync.com/api-reference/syncs/app-schema/generate_app_schema

`POST https://api.stacksync.com/v1/workspaces/{workspace_id}/helpers/generate-app-schema`

- Operation: `generate_app_schema`
- Resource: App schema
- Access: writes data

## Authentication

- `Authorization: Bearer <key>`: A workspace API key (workspace_…, created by a workspace owner under Workspace settings > Stacksync API) acts with editor rights on that workspace only; a user API key (user_…, created under Profile > Stacksync API) acts as that user in every workspace they belong to. POST, PUT and PATCH requests must send Content-Type: application/json. Every authentication failure answers 403.
- `Content-Type: application/json` on every request with a body.

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace_id` | integer | Yes | The workspace the resources belong to |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `region` | string (besg \| usnv) | Yes | Data region of the connection |

## Request body

`application/json`. The connection and the tables to read the columns of

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `connection_id` | string (uuid) | Yes | The connection to read the schema through |
| `table_names` | array of string, default [] | No | The tables to read the columns of, by `table_name` or `table_id` exactly as the schema lists them; the answer lists every table but fills `columns` for these only |

## Returns

### 200 The tables of the app, with the columns of the tables named

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `app_type` | string | Yes | The app of the connection, as shown in Stacksync |
| `can_create_tables` | boolean | Yes | Whether a sync may create a new table in this app (`table_options.create_new_table: true`) |
| `tables` | array of object (AppSchemaTable) | Yes | Every table of the app |
| `tables[].table_name` | string | Yes | The name of the table in the app: the value to send as `table_name` when creating a sync (its id is accepted too) |
| `tables[].table_id` | string | Yes | The id of the table in the app, when the app has one apart from the name (BigQuery: `project.dataset.table`) |
| `tables[].table_options` | object (AppSchemaTableOptions) | Yes | The options of a table of the app |
| `tables[].table_options.primary_key` | object (AppSchemaPrimaryKey) | No | The primary key of a table |
| `tables[].table_options.primary_key.column_name` | string | No | The name of the primary key column |
| `tables[].table_options.primary_key.column_type` | string | No | The Stacksync type of the column (for example `string`, `int`, `uuid`, `datetime`) |
| `tables[].columns` | array of object (AppSchemaColumn) | Yes | The columns of the table; only filled for the tables named in `table_names`, empty for the others |
| `tables[].columns[].column_name` | string | Yes | The name of the column in the app: the value to send as `column_name` when creating a sync |
| `tables[].columns[].column_type` | string | Yes | The Stacksync type of the column (for example `string`, `int`, `number`, `boolean`, `datetime`, `uuid`, `json`) |
| `tables[].columns[].writable` | boolean | No | Whether a sync can write to the column; absent when the app does not say |

## Example request

```bash
curl -X POST "https://api.stacksync.com/v1/workspaces/{workspace_id}/helpers/generate-app-schema?region=besg" \
  -H "Authorization: Bearer $STACKSYNC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "connection_id": "9b2e4f60-1c3d-4a5e-8f70-2d4c6e8a0b12",
  "table_names": [
    "accounts"
  ]
}'
```

## Example response (200)

```json
{
  "app_type": "postgres",
  "can_create_tables": true,
  "tables": [
    {
      "table_name": "accounts",
      "table_id": "accounts",
      "table_options": {
        "primary_key": {
          "column_name": "id",
          "column_type": "uuid"
        }
      },
      "columns": [
        {
          "column_name": "id",
          "column_type": "uuid",
          "writable": false
        },
        {
          "column_name": "name",
          "column_type": "string",
          "writable": true
        },
        {
          "column_name": "website",
          "column_type": "string",
          "writable": true
        }
      ]
    },
    {
      "table_name": "contacts",
      "table_id": "contacts",
      "table_options": {},
      "columns": []
    }
  ]
}
```

## Errors

| Status | Meaning | Body |
| --- | --- | --- |
| 400 | The `region` is missing or not one of besg, usnv; the body is not a JSON object; `connection_id` is missing or not a UUID; `table_names` is not an array of strings; the app does not support syncs (`App Not Supported`); the app refused the credentials (`Connection Authorization Error`); Stacksync could not connect to the app (`Connection Error`); the schema could not be read (`Error generating app schema`) | `{ "error": string }` |
| 403 | Forbidden: invalid API key, API key of another workspace, insufficient scope, workspace unavailable, or a non-GET request without `Content-Type: application/json` | `{ "error": string }` |
| 404 | The connection does not exist in the workspace and region, or is not visible to the user of the API key (`Error retrieving connection`) | `{ "error": string }` |

## Related

- [API Reference overview](https://docs.stacksync.com/api-reference): base URLs, regions, pagination, idempotency and errors
- [Authentication](https://docs.stacksync.com/api-reference/authentication): API keys and the 403 answers
- OpenAPI document: https://docs.stacksync.com/openapi.json
- [Get an app schema](https://docs.stacksync.com/api-reference/syncs/app-schema/get_app_schema)