Profile & Preferences
User settings, themes, and customization.
PUT /api/users/{username}/theme
Set a user's theme preference.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
username | string | Username |
Request Body:
A raw string (the theme identifier), not a JSON object. Stored under the user's data.theme.
"midnight"
Response:
Returns the updated user object.
"midnight"
{
"_links": {
"self": {
"href": "https://informer.example.com/api/users/annie.larson/theme"
},
"inf:memberships": {
"href": "https://informer.example.com/api/users/annie.larson/theme/memberships"
},
"inf:avatar-upload": {
"href": "https://informer.example.com/api/users/annie.larson/theme/_upload/{uploadId}/avatar-upload",
"templated": true
},
"inf:password": {
"href": "https://informer.example.com/api/users/annie.larson/theme/password"
},
"inf:feed": {
"href": "https://informer.example.com/api/users/annie.larson/theme/feed"
},
"inf:viewed-feed": {
"href": "https://informer.example.com/api/users/annie.larson/theme/_markFeedViewed"
},
"inf:superuser": {
"href": "https://informer.example.com/api/users/annie.larson/theme/superuser"
}
},
"permissions": {
"changeDomain": true,
"changeProfile": true,
"changePassword": true,
"delete": true,
"edit": true,
"reassign": true,
"superuser": true,
"enable": true,
"changeTheme": true,
"lock": true,
"setGlobalPermissions": true,
"manageLogin": true
},
"domain": "local",
"username": "annie.larson",
"displayName": "Annie Larson",
"familyName": null,
"givenName": null,
"middleName": null,
"email": "annie.larson@example.com",
"data": {
"theme": "midnight"
},
"superuser": false,
"timezone": "America/New_York",
"settings": {
"log": {
"log": false,
"info": false,
"warn": false,
"debug": false,
"error": true,
"remote": false
}
},
"enabled": true,
"source": null,
"sourceId": null,
"lastViewedFeed": null,
"tenant": "acme",
"globalPermissions": {
"ai": false,
"jobCreation": false,
"viewAllTeams": false,
"viewAllUsers": false,
"painlessScriptCreation": false
},
"userFields": {},
"locked": false,
"lockedAt": null,
"loginAttempts": 0,
"passwordSetAt": "2026-01-15T16:20:00.000Z",
"passwordExpiresAt": "2026-01-15T16:20:00.000Z",
"forgotPasswordRequestTime": null,
"mfa": null,
"mfaConfig": {},
"aiMessage": null,
"aiConsent": false,
"hasSharedDatasources": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"teams": [],
"initials": "AL",
"colorIndex": 4,
"avatarColor": {
"background": "#81C784",
"text": "#1B5E20"
},
"managesPassword": true
}
GET /api/top-menu-templates
Get the new-content menu templates for the calling user. Drives the global "+ New" menu.
Authentication: Required
Response:
An object keyed by content type (datasets, reports, apps, ...). Each entry the caller can create lists its available templates. AI-gated types only appear when AI is licensed.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/top-menu-templates"
}
},
"datasets": {
"templates": [
{
"detective": "00000000-0000-4000-8000-000000000001",
"id": "00000000-0000-4000-8000-000000000001:0",
"value": {
"group": "__top",
"groupPriority": 500,
"name": "Upload a File",
"priority": 100,
"editorComponent": {
"newDatasetDialog": {
"name": "Upload a File",
"description": "Create a Dataset from a File containing data, such as an Excel Spreadsheet",
"color": "blueGrey",
"component": "newDatasetFileUploadEditor"
}
},
"dataset": {}
}
},
{
"detective": "00000000-0000-4000-8000-000000000002",
"id": "00000000-0000-4000-8000-000000000002:0",
"value": {
"group": "__top",
"groupPriority": 1000,
"name": "Native SQL",
"priority": 10,
"iconSvg": "/images/query/native-sql-query.svg",
"editOnCreate": true,
"editorComponent": {
"newDatasetDialog": {
"name": "Native SQL",
"description": "Create a Dataset based on your own SQL statement",
"iconSvg": "/images/query/native-sql-query.svg",
"color": "deepPurple",
"component": {
"newDatasetNativeSqlEditor": {
"datasources": [
{
"defaultLinkType": "sql",
"aiSystemMessage": "This is a PostgresSQL database. Identifiers are case-sensitive by default. \n Always surround all column names, table names, and schema names in double-quotes (\"). \n For example:\n SELECT \"OrderID\", \"ShipCountry\" FROM \"public\".\"orders\" WHERE \"ShipCity\" = 'Raleigh';\n ---",
"family": "sql",
"languages": [
"informer",
"sql",
"distinctValue",
"… 2 more items (5 total) — omitted from docs"
],
"naturalId": "admin:northwind",
"image": "/opt/informer/packages/informer-server/modules/sql/images/postgres.svg",
"compatibility": [],
"permissions": {
"assignTags": false,
"edit": false,
"delete": false,
"share": false,
"write": false,
"changeOwner": false,
"ping": false,
"scan": false,
"downloadSchema": false,
"importData": false,
"importSchema": false,
"rename": false,
"editConnection": false,
"createLink": false,
"setWrite": false,
"createSuite": false,
"createFieldExpression": false,
"createMapping": false,
"bundle": false,
"query": false
},
"id": "00000000-0000-4000-8000-000000000003",
"tenant": "acme",
"ownerId": "admin",
"slug": "northwind",
"name": "Northwind",
"description": null,
"embedded": false,
"type": "postgres",
"connection": {
"host": "localhost",
"pool": {
"max": 5,
"min": 0,
"idle": 10000,
"acquire": 10000
},
"port": 5432,
"user": "northwinduser",
"database": "northwind",
"password": "encrypted:iv:0000000000000000",
"idleTimeoutMillis": 7
},
"scannedAt": "2026-01-15T16:20:00.000Z",
"schemaUpdatedAt": "2026-01-15T16:20:00.000Z",
"rescanRequired": false,
"shared": false,
"schemas": [
"public"
],
"source": null,
"sourceId": null,
"settings": {
"multiSchema": false,
"useFakeData": false,
"remoteQueryBatchSize": {
"multiKey": 500,
"singleKey": 500
},
"usePreparedStatements": false
},
"data": null,
"appId": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"fileId": null
}
]
}
}
}
},
"dataset": {
"query": {}
}
}
},
{
"detective": "00000000-0000-4000-8000-000000000004",
"id": "00000000-0000-4000-8000-000000000004:0",
"value": {
"group": "Northwind",
"groupPriority": 10,
"name": "Northwind Orders",
"description": "A pre-built Dataset that shows all the orders in the Northwind Datasource",
"image": "/opt/informer/packages/informer-server/modules/sql/images/postgres.svg",
"editorComponent": {
"newDatasetDialog": {
"name": "Northwind Orders",
"description": "A pre-built Dataset that shows all the orders in the Northwind Datasource",
"materialIcon": "shopping_cart",
"color": "blue",
"component": "newDatasetBasicEditor"
}
},
"dataset": {
"name": "Northwind Orders",
"description": "A Dataset consisting of all orders in the Northwind system (public schema)",
"namespace": "admin",
"source": "northwind-datasets",
"query": {
"embedded": true,
"language": "informer",
"datasourceId": "00000000-0000-4000-8000-000000000003",
"flow": [
{
"calculatedField": {
"alias": "salesperson",
"label": "Salesperson",
"script": "FirstName + ' ' + LastName"
}
},
{
"calculatedField": {
"alias": "orderAmount",
"label": "Order Amount",
"script": "UnitPrice * Quantity"
}
},
{
"calculatedField": {
"alias": "shipState",
"label": "Ship State",
"script": "ShipCountry === \"USA\" ? ShipRegion : null"
}
}
],
"payload": {
"source": {
"id": "00000000-0000-4000-8000-000000000003:public+orders",
"mappingId": "orders",
"schemaId": "public"
},
"fields": [
{
"id": "OrderDate",
"path": "OrderDate",
"type": "field",
"label": "Order Date",
"fieldId": "OrderDate",
"linkRef": null,
"rawType": "date",
"dataType": "date_tz",
"position": 0
},
{
"id": "RequiredDate",
"path": "RequiredDate",
"type": "field",
"label": "Required Date",
"fieldId": "RequiredDate",
"linkRef": null,
"rawType": "date",
"dataType": "date_tz",
"position": 1
},
{
"id": "ShipAddress",
"path": "ShipAddress",
"type": "field",
"label": "Ship Address",
"fieldId": "ShipAddress",
"linkRef": null,
"rawType": "character varying",
"dataType": "keyword_text",
"position": 2
},
"… 10 more items (13 total) — omitted from docs"
],
"linkRefs": [
{
"id": "employees",
"linkId": "00000000-0000-4000-8000-000000000003:public+orders:employees",
"details": {
"id": "00000000-0000-4000-8000-000000000003:public+orders:employees",
"defn": [
{
"toField": "EmployeeID",
"operator": "=",
"fromField": "EmployeeID",
"toMapping": "employees",
"fromMapping": "orders",
"toSchema": "public",
"fromSchema": "public"
}
],
"toId": "00000000-0000-4000-8000-000000000003:public+employees",
"type": "sql",
"fromId": "00000000-0000-4000-8000-000000000003:public+orders",
"linkId": "employees"
}
},
{
"id": "order-details",
"linkId": "00000000-0000-4000-8000-000000000003:public+orders:order-details",
"details": {
"id": "00000000-0000-4000-8000-000000000003:public+orders:order-details",
"defn": [
{
"toField": "OrderID",
"operator": "=",
"fromField": "OrderID",
"toMapping": "order_details",
"fromMapping": "orders",
"toSchema": "public",
"fromSchema": "public"
}
],
"toId": "00000000-0000-4000-8000-000000000003:public+order_details",
"type": "sql",
"fromId": "00000000-0000-4000-8000-000000000003:public+orders",
"linkId": "order-details"
}
},
{
"id": "order-details/products",
"linkId": "00000000-0000-4000-8000-000000000003:public+order_details:products",
"details": {
"id": "00000000-0000-4000-8000-000000000003:public+order_details:products",
"defn": [
{
"toField": "ProductID",
"operator": "=",
"fromField": "ProductID",
"toMapping": "products",
"fromMapping": "order_details",
"toSchema": "public",
"fromSchema": "public"
}
],
"toId": "00000000-0000-4000-8000-000000000003:public+products",
"type": "sql",
"fromId": "00000000-0000-4000-8000-000000000003:public+order_details",
"linkId": "products"
}
}
]
}
}
}
}
},
"… 1 more items (4 total) — omitted from docs"
]
},
"datasources": {
"templates": [
{
"detective": "00000000-0000-4000-8000-000000000006",
"id": "00000000-0000-4000-8000-000000000006:0",
"value": {
"group": "SQL",
"name": "Generic JDBC",
"edit": "/opt/informer/packages/informer-server/modules/sql/generic-jdbc/connection-tpl.html",
"datasource": {
"type": "generic-jdbc",
"connection": {},
"settings": {
"usePreparedStatements": true
}
}
}
},
{
"detective": "00000000-0000-4000-8000-000000000007",
"id": "00000000-0000-4000-8000-000000000007:0",
"value": {
"group": "SQL",
"name": "Microsoft SQL Server",
"edit": "/opt/informer/packages/informer-server/modules/sql/generic-jdbc/connection-tpl.html",
"datasource": {
"type": "mssql-jdbc",
"connection": {
"driverClass": "com.microsoft.sqlserver.jdbc.SQLServerDriver",
"additionalProperties": {
"user": "",
"password": "",
"databaseName": "",
"selectMethod": "cursor",
"sendTimeAsDatetime": false
}
},
"settings": {
"usePreparedStatements": true,
"multiSchema": true
}
}
}
},
{
"detective": "00000000-0000-4000-8000-000000000008",
"id": "00000000-0000-4000-8000-000000000008:0",
"value": {
"group": "SQL",
"name": "MySQL",
"edit": "/opt/informer/packages/informer-server/modules/sql/mysql/connection-tpl.html",
"datasource": {
"type": "mysql",
"connection": {},
"settings": {
"usePreparedStatements": true
}
}
}
},
"… 12 more items (15 total) — omitted from docs"
]
},
"reports": {
"templates": [
{
"detective": "00000000-0000-4000-8000-000000000020",
"id": "00000000-0000-4000-8000-000000000020:0",
"value": {
"group": "Ad hoc Query",
"name": "Native SQL",
"priority": 200,
"iconSvg": "/images/query/native-sql-query.svg",
"language": "sql",
"editOnCreate": true,
"rel": "inf:queries",
"searchDriver": "adhoc",
"editorComponent": {
"newReportDialog": {
"name": "Ad hoc Native SQL Query",
"description": "Write your own Query through a SQL statement",
"iconSvg": "/images/query/native-sql-query.svg",
"color": "deepPurple",
"component": {
"newNativeSqlEditor": {
"datasources": [
{
"defaultLinkType": "sql",
"aiSystemMessage": "This is a PostgresSQL database. Identifiers are case-sensitive by default. \n Always surround all column names, table names, and schema names in double-quotes (\"). \n For example:\n SELECT \"OrderID\", \"ShipCountry\" FROM \"public\".\"orders\" WHERE \"ShipCity\" = 'Raleigh';\n ---",
"family": "sql",
"languages": [
"informer",
"sql",
"distinctValue",
"… 2 more items (5 total) — omitted from docs"
],
"naturalId": "admin:northwind",
"image": "/opt/informer/packages/informer-server/modules/sql/images/postgres.svg",
"compatibility": [],
"permissions": {
"assignTags": false,
"edit": false,
"delete": false,
"share": false,
"write": false,
"changeOwner": false,
"ping": false,
"scan": false,
"downloadSchema": false,
"importData": false,
"importSchema": false,
"rename": false,
"editConnection": false,
"createLink": false,
"setWrite": false,
"createSuite": false,
"createFieldExpression": false,
"createMapping": false,
"bundle": false,
"query": false
},
"id": "00000000-0000-4000-8000-000000000003",
"tenant": "acme",
"ownerId": "admin",
"slug": "northwind",
"name": "Northwind",
"description": null,
"embedded": false,
"type": "postgres",
"connection": {
"host": "localhost",
"pool": {
"max": 5,
"min": 0,
"idle": 10000,
"acquire": 10000
},
"port": 5432,
"user": "northwinduser",
"database": "northwind",
"password": "encrypted:iv:0000000000000000",
"idleTimeoutMillis": 7
},
"scannedAt": "2026-01-15T16:20:00.000Z",
"schemaUpdatedAt": "2026-01-15T16:20:00.000Z",
"rescanRequired": false,
"shared": false,
"schemas": [
"public"
],
"source": null,
"sourceId": null,
"settings": {
"multiSchema": false,
"useFakeData": false,
"remoteQueryBatchSize": {
"multiKey": 500,
"singleKey": 500
},
"usePreparedStatements": false
},
"data": null,
"appId": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"fileId": null
}
]
}
}
}
},
"report": {
"language": "sql"
}
}
},
{
"detective": "00000000-0000-4000-8000-000000000021",
"id": "00000000-0000-4000-8000-000000000021:0",
"value": {
"group": "Pixel Perfect",
"name": "Template",
"priority": 100,
"iconSvg": "/assets/reports/images/template.svg",
"editOnCreate": true,
"draftPrepared": true,
"rel": "inf:templates",
"searchDriver": "template",
"editorComponent": {
"newReportDialog": {
"name": "New Template",
"description": "Create a new templated rich document that can bind content to data from Datasets, Ad hoc Queries, and Files",
"iconSvg": "/assets/reports/images/template.svg",
"component": "newTemplateReport"
}
},
"report": {
"type": "nunjucks",
"handler": "pdf",
"handlerOptions": {
"letterheadOverrides": {},
"manualOptions": {
"fontName": "Roboto",
"fontSize": 11,
"pageSize": "letter",
"orientation": "Portrait",
"marginTop": 10,
"marginBottom": 10,
"marginLeft": 10,
"marginRight": 10,
"footer": {},
"header": {}
}
},
"initialFiles": [
{
"primary": true,
"role": "TEMPLATE",
"filename": "template.njk",
"contentType": "text/html",
"payload": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"UTF-8\">\n <link rel=\"stylesheet\" href=\"{{url('style.css')}}\">\n</head>\n\n<body>\n <div>Hello, world!</div>\n</body>\n\n</html>"
},
{
"role": "ASSET",
"filename": "style.css",
"contentType": "text/css"
},
{
"role": "TEMPLATE",
"filename": "helpers.js",
"contentType": "application/javascript"
}
]
}
}
},
{
"detective": "00000000-0000-4000-8000-000000000022",
"id": "00000000-0000-4000-8000-000000000022:0",
"value": {
"group": "Ad hoc Query",
"name": "Query Designer",
"priority": 100,
"iconSvg": "/assets/query-languages/images/query-designer.svg",
"language": "informer",
"editOnCreate": true,
"rel": "inf:queries",
"searchDriver": "adhoc",
"editorComponent": {
"newReportDialog": {
"name": "Ad hoc Query",
"description": "Design a Query by choosing rows and columns from a Datasource",
"iconSvg": "/assets/query-languages/images/query-designer.svg",
"color": "blue",
"component": "newQueryDesigner"
}
},
"report": {
"language": "informer"
}
}
},
"… 3 more items (6 total) — omitted from docs"
]
},
"jobs": {
"templates": [
{
"detective": "00000000-0000-4000-8000-000000000026",
"id": "00000000-0000-4000-8000-000000000026:0",
"value": {
"group": "__top",
"name": "New Job",
"description": "Choose Datasets and Queries to back multiple actions, such as sending an email.",
"materialIcon": "lightbulb_outline",
"job": {
"type": "smart-job",
"data": {}
}
}
}
]
},
"teams": {
"templates": true
},
"users": {
"templates": true
},
"queries": {
"templates": [
{
"detective": "00000000-0000-4000-8000-000000000027",
"id": "00000000-0000-4000-8000-000000000027:0",
"value": {
"group": "Datasource",
"name": "Native SQL",
"editOnCreate": true,
"iconSvg": "/images/query/native-sql-query.svg",
"editorComponent": {
"newNativeSqlEditor": {
"datasources": [
{
"defaultLinkType": "sql",
"aiSystemMessage": "This is a PostgresSQL database. Identifiers are case-sensitive by default. \n Always surround all column names, table names, and schema names in double-quotes (\"). \n For example:\n SELECT \"OrderID\", \"ShipCountry\" FROM \"public\".\"orders\" WHERE \"ShipCity\" = 'Raleigh';\n ---",
"family": "sql",
"languages": [
"informer",
"sql",
"distinctValue",
"… 2 more items (5 total) — omitted from docs"
],
"naturalId": "admin:northwind",
"image": "/opt/informer/packages/informer-server/modules/sql/images/postgres.svg",
"compatibility": [],
"permissions": {
"assignTags": false,
"edit": false,
"delete": false,
"share": false,
"write": false,
"changeOwner": false,
"ping": false,
"scan": false,
"downloadSchema": false,
"importData": false,
"importSchema": false,
"rename": false,
"editConnection": false,
"createLink": false,
"setWrite": false,
"createSuite": false,
"createFieldExpression": false,
"createMapping": false,
"bundle": false,
"query": false
},
"id": "00000000-0000-4000-8000-000000000003",
"tenant": "acme",
"ownerId": "admin",
"slug": "northwind",
"name": "Northwind",
"description": null,
"embedded": false,
"type": "postgres",
"connection": {
"host": "localhost",
"pool": {
"max": 5,
"min": 0,
"idle": 10000,
"acquire": 10000
},
"port": 5432,
"user": "northwinduser",
"database": "northwind",
"password": "encrypted:iv:0000000000000000",
"idleTimeoutMillis": 7
},
"scannedAt": "2026-01-15T16:20:00.000Z",
"schemaUpdatedAt": "2026-01-15T16:20:00.000Z",
"rescanRequired": false,
"shared": false,
"schemas": [
"public"
],
"source": null,
"sourceId": null,
"settings": {
"multiSchema": false,
"useFakeData": false,
"remoteQueryBatchSize": {
"multiKey": 500,
"singleKey": 500
},
"usePreparedStatements": false
},
"data": null,
"appId": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"fileId": null
}
]
}
},
"language": "sql",
"query": {}
}
},
{
"detective": "00000000-0000-4000-8000-000000000028",
"id": "00000000-0000-4000-8000-000000000028:0",
"value": {
"group": "Datasource",
"name": "Ad hoc Query",
"iconSvg": "/assets/query-languages/images/query-designer.svg",
"editOnCreate": true,
"editorComponent": "newQueryDesigner",
"language": "informer",
"query": {}
}
}
]
},
"integrations": {
"templates": [
{
"detective": "00000000-0000-4000-8000-000000000029",
"id": "00000000-0000-4000-8000-000000000029:0",
"value": {
"group": "__top",
"name": "API Connection",
"image": "/images/icons/plug.svg",
"createEditor": "apiIntegrationEditor",
"description": "Set up a connection to an external service as a new Integration.",
"needsConfiguration": true,
"integration": {
"type": "api"
}
}
},
{
"detective": "00000000-0000-4000-8000-000000000030",
"id": "00000000-0000-4000-8000-000000000030:0",
"value": {
"group": "__top",
"name": "Google Drive™",
"image": "/images/icons/googledrive.svg",
"createEditor": {
"clientIdSecretForm": {
"clientId": null
}
},
"description": "Connect to your Google Drive account through an Integration. Once connected, you can use the \"Upload to Drive\" action in Jobs to send files to your Google Drive.",
"needsConfiguration": false,
"integration": {
"type": "googledrive",
"category": "Google Drive",
"name": "Google Drive™",
"imageUrl": "/images/icons/googledrive.svg",
"authUri": "https://accounts.google.com/o/oauth2/auth",
"revocationUri": "https://oauth2.googleapis.com/revoke",
"apiBaseUri": "https://www.googleapis.com",
"clientId": null,
"basicTokenAuth": false,
"scope": "https://www.googleapis.com/auth/drive.file",
"tokenUri": "https://oauth2.googleapis.com/token"
}
}
},
{
"detective": "00000000-0000-4000-8000-000000000031",
"id": "00000000-0000-4000-8000-000000000031:0",
"value": {
"group": "__top",
"name": "Microsoft OneDrive®",
"image": "/images/icons/office.svg",
"createEditor": {
"clientIdSecretForm": {
"clientId": null
}
},
"description": "Connect to your Microsoft OneDrive account through an Integration. Once connected, you can use the \"Upload to Drive\" action in Jobs to send files to your OneDrive.",
"needsConfiguration": false,
"integration": {
"type": "onedrive",
"category": "OneDrive",
"name": "Microsoft OneDrive®",
"imageUrl": "/images/icons/office.svg",
"authUri": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
"revocationUri": "https://login.microsoftonline.com/common/oauth2/v2.0/logout",
"apiBaseUri": "https://graph.microsoft.com/v1.0",
"clientId": null,
"basicTokenAuth": false,
"scope": "openid profile files.readwrite files.readwrite.all offline_access user.read Sites.Read.All Team.ReadBasic.All",
"tokenUri": "https://login.microsoftonline.com/common/oauth2/v2.0/token"
}
}
}
]
}
}
Use Case:
Render the "create new" menu with only the content types the user is allowed to create.
User Settings
Per-user preferences are stored in the settings JSONB field. Update them via PUT /api/users/\{username\} (admin) or PUT /api/me (self) with a settings object. Typical contents:
{
"settings": {
"language": "en",
"dateFormat": "MM/DD/YYYY",
"timeFormat": "12h",
"pageSize": 50
}
}
GET /api/users/{username}/memberships
Get a user's team memberships.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
username | string | Username |
Response:
A HAL collection under _embedded["inf:membership"]; each membership embeds its team and access level.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/users/admin/memberships"
}
},
"start": 0,
"count": 0,
"total": 0,
"_embedded": {
"inf:membership": []
}
}
Use Case:
Display all teams a user belongs to and their roles.