Skip to content
Docs
Email & messaging

Gmail

Let hires read, search, reply to and send email in a Gmail or Google Workspace mailbox.

Explore 10 actions and their permissionsExact inputs, sign-in scopes, access limits and approval rules.

With Gmail connected, a hire can list and search mail in the labels you allow, read a message or a whole conversation, draft a reply for someone to check, reply and send new mail, and move or mark messages. Replies stay in their conversation. It works the same way as Email, so a hire that knows one mailbox knows them all.

Mail goes out in your business's name, like "Bayt Studio Accounts", never a made-up person's. Every email ends with that name as its signature.

Labels are folders here: INBOX, SENT, DRAFT, SPAM, TRASH, and your own labels like Invoices. Moving a message to a label adds that label and takes away the one it was in.

1. Make an app in Google Cloud

Roster connects as an app you own, so you choose what it can reach and can revoke it at any time. One app can serve Gmail, Google Calendar and Google Drive.

  1. Open console.cloud.google.com, and create a project (or pick one).
  2. APIs & Services → Library: search for Gmail API and click Enable.
  3. APIs & Services → OAuth consent screen:
    • With Google Workspace, choose Internal: only people in your organisation can connect, and Google doesn't need to review the app.
    • With a personal Gmail account, choose External, add yourself as a test user, and then Publish app. While an External app is in testing, Google stops its access after 7 days and you'd have to connect again. Google shows a warning while it hasn't verified the app; that's expected for an app only you use.
  4. Add the scope https://www.googleapis.com/auth/gmail.modify.
  5. APIs & Services → Credentials → Create credentials → OAuth client ID, type Web application. Under Authorized redirect URIs, add the address Roster shows on the Gmail connection. It ends in /api/integrations/gmail/oauth/callback.
  6. Copy the Client ID and Client secret.

We suggest a mailbox just for the hire's work, like accounts@yourbusiness.com, so you can see everything it sends and receives.

2. Connect it in Roster

  1. Open Integrations → Tools → Add a tool, search for Gmail and choose it.
  2. Paste the OAuth app client ID and OAuth app client secret.
  3. From name: your business or team name, used as the sender's name and in the signature.
  4. From address: leave it empty to send from the mailbox's own address, or give one of its send-as addresses (Gmail settings → Accounts).
  5. Click Connect, then Connect with Gmail on the new connection, and sign in to the mailbox hires should use. Click Allow.

What Roster asks Google for

PermissionWhy
Read, compose and send email (gmail.modify)Read mail; draft, send, label and mark it (only hires allowed to)

It can't delete mail permanently.

3. Give hires access

On the hire's Tools tab, click Give access on Gmail:

  • Read only: it can list labels, list, search and read messages and conversations, and nothing else.
  • Read and write: it can also draft replies, reply, send new mail, and move and mark messages.
  • Folders: the labels it may use, like INBOX or Invoices. Leave it empty for every label. Messages without one of these labels are refused.
  • Who it may email: domains it may send to, like yourclient.com. Leave it empty to let it email anyone.

If you'd like to check emails before they go, give the hire Read and write and ask it to draft replies: they wait in Gmail's Drafts, in their conversation, for someone to send.

First emails to new people

A first email to someone outside your team that this mailbox has never written to waits for a person's approval: the hire asks in the thread with the recipient and the message, and when the approver says yes, Roster sends exactly that email. After that, writing to them again doesn't ask, and replies never do. People at your team's domains never count as new. To change this for a hire, use When it asks first on its Tools tab.

Saying it's an AI assistant

A hire never pretends to be a person, and always says it's AI when asked. If you also want every email to say so up front, turn on Say it's an AI assistant in first messages to outsiders under Settings → Workspace (more). Each email's signature then adds a line saying an AI assistant wrote it for your business.

Waking a hire when mail arrives

A hire's responsibility can watch Gmail: when new mail lands in its labels (or the inbox, if it has none listed), the hire is woken with a line for each new email. Checking costs nothing when nothing arrived.

If something goes wrong

  • "Isn't connected yet": press Connect with Gmail on the connection.
  • Google says the redirect URI doesn't match: the address in Google Cloud must be exactly the one Roster shows.
  • It worked for a week, then stopped: the app is External and still in testing. Publish it in the OAuth consent screen, then connect again.
  • "Access blocked": the app is Internal but the mailbox is outside your organisation, or the mailbox isn't a test user of an External app in testing.

Tools and permissions reference

This reference is built from the same definitions Roster uses to connect Gmail and give hires access. It updates with each release.

Authentication and requested permissions

The account or app you connect sets the outer limit. Each hire's access can narrow it further. Connecting a tool gives it to no hire until you give access on that hire's Tools tab.

OAuth 2.0

From the OAuth client (Web application) you created in Google Cloud for Roster.

Requested scopes:

  • https://www.googleapis.com/auth/gmail.modify

Connection fields

Gmail connection fields
FieldWhat to provide
OAuth app client ID
clientId
Optional
From the OAuth client (Web application) you created in Google Cloud for Roster.
OAuth app client secret
clientSecret
Optional · sealed secret
Use the value for your account or connection.
From name
fromName
Required
Your business or team name, used in the signature of every email. Never a made-up person's name.
From address
fromAddress
Optional
Leave empty to send from the mailbox's own address. Or one of its send-as addresses (Gmail settings → Accounts).

Per-hire limits

Read-only hires receive only actions that read. Read-and-write access also allows actions that change things, where the connection itself permits them. An empty resource allowlist usually means everything the connected account can reach; each field below explains its meaning.

Gmail per-hire limits
FieldWhat to provide
Folders
folders
Optional
Folders the hire may read and change, like INBOX or Invoices. Leave empty for every folder. A watch checks these (or INBOX).
Who it may email
recipientDomains
Optional
Domains the hire may send to, like example.com. Leave empty to let it email anyone.

Actions

10 actions: 5 only read and 5 change something. A read action may still need approval when your workspace or hire is set to ask. A locked approval requirement always applies.

10 of 10 actions. Open an action for its arguments and full input schema.

list_foldersRead only

The mail folders this hire can use, with how many messages and unread ones each has.

Approval: Uses your workspace and hire approval settings.

This action takes no arguments.

Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {}
}
list_messagesRead only

The newest messages in a folder, newest first: id, date, sender, subject, and whether read.

Approval: Uses your workspace and hire approval settings.

Arguments for list_messages
ArgumentTypeDetails
folderOptionalstringfolder, e.g. INBOXDefault: "INBOX"
unread_onlyOptionalbooleanSee input schema below.Default: false
limitOptionalintegerSee input schema below.Default: 20
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "folder": {
      "default": "INBOX",
      "description": "folder, e.g. INBOX",
      "type": "string",
      "minLength": 1
    },
    "unread_only": {
      "default": false,
      "type": "boolean"
    },
    "limit": {
      "default": 20,
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    }
  }
}
searchRead only

Search a folder by words (in the subject or text), sender, subject or date. Newest matches first.

Approval: Uses your workspace and hire approval settings.

Arguments for search
ArgumentTypeDetails
folderOptionalstringfolder, e.g. INBOXDefault: "INBOX"
textOptionalstringwords anywhere in the message
fromOptionalstringpart of the sender's address or name
subjectOptionalstringSee input schema below.
sinceOptionalstringonly messages on or after this day, YYYY-MM-DD
unread_onlyOptionalbooleanSee input schema below.Default: false
limitOptionalintegerSee input schema below.Default: 20
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "folder": {
      "default": "INBOX",
      "description": "folder, e.g. INBOX",
      "type": "string",
      "minLength": 1
    },
    "text": {
      "description": "words anywhere in the message",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "from": {
      "description": "part of the sender's address or name",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "subject": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "since": {
      "description": "only messages on or after this day, YYYY-MM-DD",
      "type": "string",
      "format": "date",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
    },
    "unread_only": {
      "default": false,
      "type": "boolean"
    },
    "limit": {
      "default": 20,
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    }
  }
}
read_messageRead only

Read one message: who it's from and to, its date, subject and Message-ID, its text and its attachments' names. Doesn't mark it read.

Approval: Uses your workspace and hire approval settings.

Arguments for read_message
ArgumentTypeDetails
idRequiredstringthe message's id, from list_messages or search
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 400,
      "description": "the message's id, from list_messages or search"
    }
  },
  "required": [
    "id"
  ]
}
read_threadRead only

Read the whole conversation a message belongs to, oldest first: each message's sender, date and own words.

Approval: Uses your workspace and hire approval settings.

Arguments for read_thread
ArgumentTypeDetails
idRequiredstringthe message's id, from list_messages or search
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 400,
      "description": "the message's id, from list_messages or search"
    }
  },
  "required": [
    "id"
  ]
}
draft_replyRead and write

Write a reply to a message and keep it as a draft for a person to check and send. It stays in the message's thread. Write the message only: no greeting-card sign-off and never a person's name. Roster adds a signature in the business's name.

Approval: Uses your workspace and hire approval settings.

Arguments for draft_reply
ArgumentTypeDetails
idRequiredstringthe message's id, from list_messages or search
bodyRequiredstringthe reply, plain text
reply_allOptionalbooleanalso to everyone else on the messageDefault: false
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 400,
      "description": "the message's id, from list_messages or search"
    },
    "body": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20000,
      "description": "the reply, plain text"
    },
    "reply_all": {
      "default": false,
      "description": "also to everyone else on the message",
      "type": "boolean"
    }
  },
  "required": [
    "id",
    "body"
  ]
}
replyRead and write

Send a reply to a message, in its thread. Write the message only: no greeting-card sign-off and never a person's name. Roster adds a signature in the business's name.

Approval: Uses your workspace and hire approval settings.

Arguments for reply
ArgumentTypeDetails
idRequiredstringthe message's id, from list_messages or search
bodyRequiredstringthe reply, plain text
reply_allOptionalbooleanalso to everyone else on the messageDefault: false
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 400,
      "description": "the message's id, from list_messages or search"
    },
    "body": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20000,
      "description": "the reply, plain text"
    },
    "reply_all": {
      "default": false,
      "description": "also to everyone else on the message",
      "type": "boolean"
    }
  },
  "required": [
    "id",
    "body"
  ]
}
sendRead and write

Send a new email (not a reply: use reply for that, so it stays in its thread). Write the message only: no greeting-card sign-off and never a person's name. Roster adds a signature in the business's name.

Approval: when it writes to someone outside your team for the first time.

Arguments for send
ArgumentTypeDetails
toRequiredstring[]email addresses
ccOptionalstring[]email addressesDefault: []
subjectRequiredstringSee input schema below.
bodyRequiredstringplain text
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "to": {
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 3
      },
      "description": "email addresses"
    },
    "cc": {
      "default": [],
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 3
      },
      "description": "email addresses"
    },
    "subject": {
      "type": "string",
      "minLength": 1,
      "maxLength": 250
    },
    "body": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20000,
      "description": "plain text"
    }
  },
  "required": [
    "to",
    "subject",
    "body"
  ]
}
moveRead and write

Move messages from one folder to another (both must be folders this hire can use).

Approval: Uses your workspace and hire approval settings.

Arguments for move
ArgumentTypeDetails
folderOptionalstringfolder, e.g. INBOXDefault: "INBOX"
idsRequiredstring[]See input schema below.
toRequiredstringthe folder to move them to
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "folder": {
      "default": "INBOX",
      "description": "folder, e.g. INBOX",
      "type": "string",
      "minLength": 1
    },
    "ids": {
      "minItems": 1,
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 400,
        "description": "the message's id, from list_messages or search"
      }
    },
    "to": {
      "type": "string",
      "minLength": 1,
      "description": "the folder to move them to"
    }
  },
  "required": [
    "ids",
    "to"
  ]
}
markRead and write

Mark messages read or unread, or flag and unflag them.

Approval: Uses your workspace and hire approval settings.

Arguments for mark
ArgumentTypeDetails
idsRequiredstring[]See input schema below.
asRequired"read" | "unread" | "flagged" | "unflagged"See input schema below.
Full input schema (JSON)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ids": {
      "minItems": 1,
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 400,
        "description": "the message's id, from list_messages or search"
      }
    },
    "as": {
      "type": "string",
      "enum": [
        "read",
        "unread",
        "flagged",
        "unflagged"
      ]
    }
  },
  "required": [
    "ids",
    "as"
  ]
}

Watches and incoming events

  • This integration supports a responsibility that watches for changes. The guide above explains what it checks and how to limit it.
  • No incoming webhook handler is declared for this integration.

Limits and troubleshooting

  • Permission errors: check both the connected account's rights and the hire's resource and read/write limits.
  • Expired or revoked access: reconnect or replace the key on the connection.
  • Rate limits and unavailable services can interrupt work. The hire's timecard records the outcome.
  • The action schema describes accepted inputs. It does not grant additional access or bypass approvals.

Service documentation · Integration source reference

On this page