# JavaScript API

## App methods

### reload()

Reloads the iframe.

### search(text)

Initiates a new search.

| Param \*required | Default | Description |
| ---------------- | ------- | ----------- |
| `text`\*         | `""`    | Search term |

### alert(options)

Displays an error modal. It only has a “Got it” action.

| Param \*required | Default                                     | Description       |
| ---------------- | ------------------------------------------- | ----------------- |
| `options`        | `{}`                                        |                   |
| `title`          | `"Error in “Your Integration” integration"` | Error title       |
| `message`        | `""`                                        | Error description |
| `note`           | `""`                                        | Error note        |

### navigate(options)

Navigate to a conversation.

| Param \*required | Default | Description     |
| ---------------- | ------- | --------------- |
| `options`        | `{}`    |                 |
| `conversationId` | `""`    | Conversation ID |

### on(event, callback, options)

Registers an event callback.

| Param \*required | Default | Description                                                                                   |
| ---------------- | ------- | --------------------------------------------------------------------------------------------- |
| `event`\*        | `""`    | [Event](#event-main_action) to register                                                       |
| `callback`\*     |         | Callback function                                                                             |
| `options`        | `{}`    |                                                                                               |
| `retroactive`    | `false` | Triggers the callback immediately if the event has occurred before the callback is registered |

### openForm(data)

Displays a form popup. Multiple forms can be stacked over each other.

\=> Promise(Object) — Resolves with Field objects

| Param \*required | Default | Description                                         |
| ---------------- | ------- | --------------------------------------------------- |
| `data`           | `{}`    |                                                     |
| `name`           | `""`    | Form title                                          |
| `fields`         | `[]`    | Array of [FormField](#object-FormField) objects     |
| `comments`       | `[]`    | Array of [FormComment](#object-FormComment) objects |
| `notes`          | `[]`    | Array of [FormNote](#object-FormNote) objects       |
| `buttons`        | `[]`    | Array of [FormButton](#object-FormButton) objects   |
| `options`        | `{}`    |                                                     |
| `autoClose`      | `true`  | Close the popup on submit                           |

### closeForm()

Closes the last open form popup.

### openSelf()

Opens the integration sidebar if closed and selects the integration.

### closeSelf()

Closes the integration sidebar if opened.

### openURL(url)

Opens the URL in a new tab on desktop. Opens in native browser or in-app browser depending on user settings on mobile.

| Param \*required | Default | Description |
| ---------------- | ------- | ----------- |
| `url`\*          | `""`    | URL string  |

### openContextMenu(data)

Opens a context menu

| Param \*required | Default | Description                                                                                                        |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `data`\*         | `{}`    |                                                                                                                    |
| `top`            | `0`     | Top position of the menu — Menu will be below that point — Note: do not set if `data.bottom` is provided           |
| `bottom`         | `null`  | Top position of the menu — Menu will be above that point — Note: do not set if `data.top` is provided              |
| `left`           | `0`     | Left position of the menu — Menu will be to the right of that point — Note: do not set if `data.right` is provided |
| `right`          | `null`  | Right position of the menu — Menu will be to the left of that point — Note: do not set if `data.left` is provided  |
| `options`\*      | `[]`    | Array of [Option](#object-Option) objects                                                                          |

### setActions(actions)

Actions are available throughout the app as an option in context menus or swipe action.

| Param \*required | Default | Description                               |
| ---------------- | ------- | ----------------------------------------- |
| `actions`        | `[]`    | Array of [Action](#object-Action) objects |

### setAsUtility()

Mark the integration as an utility integration. It will not display the iframe in the integration sidebar. Useful for integrations that only display actions in context menus.

### setPermissions(permissions)

Make Missive requests certain media permissions. Required on macOS for integrations that require Camera or Microphone usage. You may need to reload the integration once Missive has been granted access.

| Param \*required | Default | Description                          |
| ---------------- | ------- | ------------------------------------ |
| `permissions`    | `{}`    |                                      |
| `camera`         | `false` | Request permission to use camera     |
| `microphone`     | `false` | Request permission to use microphone |

### storeGet(key)

Retrieve data that has been previously stored using `storeSet`. The data is persistent between page reloads and app reloads.

| Param \*required | Default | Description                                                                 |
| ---------------- | ------- | --------------------------------------------------------------------------- |
| `key`\*          | `""`    | A unique identifier used when storing the data using `storeSet(key, data)`. |

### storeSet(key, data)

Store data that remains consistent between page reloads and app reloads.

| Param \*required | Default | Description                                                                                                       |
| ---------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
| `key`\*          | `""`    | A unique identifier for the data to be stored. This key is used to retrieve the data later using `storeGet(key)`. |
| `data`\*         | `{}`    | The data (String, Array or Object) to be stored.                                                                  |

Example usage:

{% code title="example.js" %}

```javascript
const userData = {
  id: '1234',
  name: 'John Doe',
  email: 'john.doe@example.com'
};

Missive.storeSet('userData', userData);

Missive.storeGet('userData')
  .then(data => {
    console.log(data);
  });
```

{% endcode %}

### respondToMessage(data)

The `respondToMessage` method can be used to send commands to the Command Bar inside the [Action](#object-Action) callback of the `command_bar` context.

| Param \*required | Default | Description                                                                        |
| ---------------- | ------- | ---------------------------------------------------------------------------------- |
| `data`\*         | `{}`    |                                                                                    |
| `commands`\*     | `{}`    | List of commands that are rendered in the command bar                              |
| `id`\*           | `""`    | Unique identifier of the command                                                   |
| `picture`        | `{}`    | An image displayed alongside the command using the `grid` layout                   |
| `src`\*          | `""`    | Path to the image                                                                  |
| `webp`           | `""`    | Optional WEBP image path that is used when the browser supports it                 |
| `alt`            | `""`    | Alt attribute for the image tag                                                    |
| `iconUrl`        | `""`    | Icon displayed alongside the command using the `list` layout                       |
| `label`          | `""`    | Text displayed with the command using the `list` layout                            |
| `payload`        | `{}`    | An object returned to the callback event of type `execute`                         |
| `closeOnExecute` | `false` | Specifies whether or not the Command Bar should close when the command is executed |

Example usage:

{% code title="command-bar.js" %}

```javascript
Missive.setActions([
  {
    label: `My command bar action`,
    contexts: ['command_bar'],
    placeholder: "Command Bar's input placeholder",
    callback: async (event, messageId) => {
      if (event.type === 'load') {
        Missive.respondToMessage(messageId, {
          commands: [
            {
              id: 'command-id',
              iconUrl: 'https://via.placeholder.com/64',
              label: 'command-text',
              payload: {},
              closeOnExecute: true,
            },
          ],
        })

        return
      }

      if (event.type === 'search') {
        const commands = searchCommands(event.value)
        Missive.respondToMessage(messageId, { commands })

        return
      }

      if (event.type === 'execute') {
        executeCommand(event.payload)

        return
      }
    },
  },
])
```

{% endcode %}

### initiateCallback(url)

Initiates an OAuth flow by opening the authentication URL in a new browser tab. This method helps work around iframe OAuth limitations and is compatible with iOS.

\=> Promise(Object) — Resolves with query parameters from the OAuth redirect

| Param \*required | Default | Description                                                          |
| ---------------- | ------- | -------------------------------------------------------------------- |
| `url`\*          | `""`    | Authentication endpoint URL that will receive a redirectTo parameter |

Example usage:

{% code title="oauth.js" %}

```javascript
async function authenticateWithOAuth() {
  try {
    // 1. Initiate OAuth flow
    const response = await Missive.initiateCallback('https://your-auth-endpoint')

    // 2. Response will contain query params from the OAuth redirect
    const { access_token } = response

    // 3. Store the token for future use
    await Missive.storeSet('oauth_token', access_token)
  } catch (error) {
    console.error('OAuth flow failed:', error)
  }
}
```

{% endcode %}

How it works:

* Missive opens the auth URL in a new browser tab
* Adds a `redirectTo` parameter to your URL
* After OAuth completion, redirect to the provided `redirectTo` URL with your tokens/data as query params
* The browser tab closes automatically
* Your integration receives the data in the `response` object

## Fetch methods

### fetchConversations(ids)

Fetches attributes for the given conversation IDs.

\=> Promise(Array) — Resolves with Conversation objects

| Param \*required | Default | Description               |
| ---------------- | ------- | ------------------------- |
| `ids`\*          | `[]`    | Array of conversation IDs |

Example usage:

{% code title="fetch-conversations.js" %}

```javascript
Missive.on('change:conversations', (ids) => {
  Missive.fetchConversations(ids).then((conversations) => {
    if (conversations.length != 1) {
      // Do nothing if multiple conversations are selected.
      return
    }

    var message = conversations[0].latest_message
    if (!message || !message.from_field) {
      // Do nothing if conversation has no message (only chat comments) or if
      // message has no From field.
      return
    }

    var from = message.from_field
    console.log('Message from:', from.name, from.address)
    console.log('Message subject:', message.subject)
  })
})
```

{% endcode %}

Available attributes for conversations:

```javascript
// Conversation
{
  id: '2b3db130-e94e-43fa-970a-63bae8cb10ee',
  color: '#ff0000',
  subject: 'Keep it secret, keep it safe',
  users: [ /* Array of User objects */ ],
  assignees: [ /* Array of User objects */ ],
  authors: [ /* Array of AddressField object */ ],
  messages_count: 1,
  messages: [/* Array of Message object (see below) */],
  latest_message: {
    id: 'daa5e30e-490b-4d54-ba7b-63f19b529ab7',
    from_field: { /* AddressField */ },
    to_fields: [ /* Array of AddressField objects */ ],
    cc_fields: [ /* Array of AddressField objects */ ],
    bcc_fields: [ /* Array of AddressField objects */ ],
    reply_to_fields: [ /* Array of AddressField objects */ ],
    subject: 'Keep it secret, keep it safe',
    preview: 'Where is it? --Gandalf',
    body: '<p>Where is it?</p><p>--<br>Gandalf</p>',
    delivered_at: 1550698870,
  },
  link: 'https://mail.missiveapp.com/#inbox/conversations/37c8d757-2a20-45f6-9aa1-dbe815d27cb0',
}
```

### fetchMessages(ids)

Fetches attributes for the given message IDs.

\=> Promise(Array) — Resolves with Message objects

| Param \*required | Default | Description          |
| ---------------- | ------- | -------------------- |
| `ids`\*          | `[]`    | Array of message IDs |

Available attributes for messages:

```javascript
// Message
{
  id: 'daa5e30e-490b-4d54-ba7b-63f19b529ab7',
  from_field: { /* AddressField */ },
  to_fields: [ /* Array of AddressField objects */ ],
  cc_fields: [ /* Array of AddressField objects */ ],
  bcc_fields: [ /* Array of AddressField objects */ ],
  reply_to_fields: [ /* Array of AddressField objects */ ],
  subject: 'Keep it secret, keep it safe',
  preview: 'Where is it? --Gandalf',
  body: '<p>Where is it?</p><p>--<br>Gandalf</p>',
  delivered_at: 1550698870,
}
```

### fetchUsers()

Fetches attributes for all users.

\=> Promise(Array) — Resolves with User objects

```javascript
// User
{
  id: '6b52b6b9-9b51-46ad-a4e3-82ef3c45512c',
  avatar_url: 'https://gravatar.com/avatar/014bcc1f9c5920c658a198e6649cd20b',
  email: 'frodo@fellowship.org',
  first_name: 'Frodo',
  last_name: 'Baggins',
  display_name: 'You',
  me: true,
}
```

### fetchLabels()

Fetches attributes for all shared labels.

{% hint style="info" %}
The scope of returned labels depends on how the integration is installed. When an integration is shared with an organization, `fetchLabels()` returns labels from that organization only. When the integration is personal (private), it returns labels from all organizations the user belongs to. If you need labels across multiple orgs, have each user install the integration privately via **Settings > Integrations** instead of sharing it at the org level.
{% endhint %}

\=> Promise(Array) — Resolves with Label objects

```javascript
// Label
{
  avatar_url: "https://…",
  color: "#000"
  description: null
  emoji: null
  id: "93c1010b-8a43-4325-a2af-b3f2d7bedfd3"
  name: "GitHub"
  organization_id: "555abd43-5d6c-426b-bcb0-84180689bc86"
  parent_id: null
  share_with_organization: true
  share_with_team_id: null
  share_with_user_ids: []
  type: "shared_label"
  visibility: "organization"
}
```

## Conversation methods

### createConversation(options)

Creates a new conversation.

| Param \*required | Default | Description                                   |
| ---------------- | ------- | --------------------------------------------- |
| `options`        | `{}`    |                                               |
| `select`         | `true`  | Navigate to the newly created conversation(s) |
| `count`          | `1`     | Number of conversations to create             |

### archive()

Archives current conversation.

### trash()

Trashes current conversation.

### moveToInbox()

Moves current conversation to Inbox.

### comment(body)

Creates a comment in the current conversation.

| Param \*required | Default | Description         |
| ---------------- | ------- | ------------------- |
| `body`\*         | `""`    | Body of the comment |

### createTask(body, completed)

Creates a task in the current conversation.

| Param \*required | Default | Description            |
| ---------------- | ------- | ---------------------- |
| `body`\*         | `""`    | Body of the task       |
| `completed`      | `false` | Mark task as completed |

### addLabels(labelIds)

Adds labels to the current conversation.

| Param \*required | Default | Description        |
| ---------------- | ------- | ------------------ |
| `labelIds`\*     | `[]`    | Array of label ids |

### removeLabels(labelIds)

Removes labels from the current conversation.

| Param \*required | Default | Description        |
| ---------------- | ------- | ------------------ |
| `labelIds`\*     | `[]`    | Array of label ids |

### close()

Closes the current conversation.

### reopen()

Reopens the current conversation.

### assign(userIds)

Assigns users to the current conversation.

| Param \*required | Default | Description                                           |
| ---------------- | ------- | ----------------------------------------------------- |
| `userIds`\*      | `[]`    | Array of user ids — Empty array removes all assignees |

### addAssignees(userIds)

Adds assignees to the current conversation.

| Param \*required | Default | Description       |
| ---------------- | ------- | ----------------- |
| `userIds`\*      | `[]`    | Array of user ids |

### removeAssignees(userIds)

Removes assignees from the current conversation.

| Param \*required | Default | Description       |
| ---------------- | ------- | ----------------- |
| `userIds`\*      | `[]`    | Array of user ids |

### setColor(color)

Sets current conversation color.

| Param \*required | Default | Description         |
| ---------------- | ------- | ------------------- |
| `color`\*        | `""`    | Color in HEX format |

### setDescription(description)

Sets current conversation description.

| Param \*required | Default | Description                     |
| ---------------- | ------- | ------------------------------- |
| `description`\*  | `""`    | Description of the conversation |

### setSubject(subject)

Sets current conversation subject.

| Param \*required | Default | Description                                                      |
| ---------------- | ------- | ---------------------------------------------------------------- |
| `subject`\*      | `""`    | Subject of the conversation — Empty or `null` resets the subject |

## Composer methods

### compose(options)

Creates a new draft in a new conversation.

| Param \*required | Default | Description                                           |
| ---------------- | ------- | ----------------------------------------------------- |
| `options`        | `{}`    |                                                       |
| `deliver`        | `false` | Instantly deliver newly created draft                 |
| `mailto`         | `{}`    |                                                       |
| `subject`        | `""`    | Draft subject                                         |
| `body`           | `""`    | Draft body                                            |
| `to_fields`      | `[]`    | Array of [AddressField](#object-AddressField) objects |
| `cc_fields`      | `[]`    | Array of [AddressField](#object-AddressField) objects |
| `bcc_fields`     | `[]`    | Array of [AddressField](#object-AddressField) objects |

### composeInConversation()

Creates a new draft in current conversation.

Same params as compose.

### reply(options)

Replies to current conversation latest message.

| Param \*required | Default | Description                           |
| ---------------- | ------- | ------------------------------------- |
| `options`        | `{}`    |                                       |
| `deliver`        | `false` | Instantly deliver newly created reply |
| `mailto`         | `{}`    | See compose method above              |

### forward(options)

Forwards current conversation latest message.

| Param \*required | Default | Description                                |
| ---------------- | ------- | ------------------------------------------ |
| `options`        | `{}`    |                                            |
| `private`        | `false` | Create draft in a new private conversation |
| `deliver`        | `false` | Instantly deliver newly created draft      |
| `mailto`         | `{}`    | See compose method above                   |

### insertText(text)

Inserts content as text in the currently selected composer.

| Param \*required | Default | Description  |
| ---------------- | ------- | ------------ |
| `text`           | `""`    | Text content |

### insertHtml(text)

Inserts content as HTML in the currently selected composer.

| Param \*required | Default | Description  |
| ---------------- | ------- | ------------ |
| `text`           | `""`    | HTML content |

## Helper methods

### isToday(date)

Tests if date is today.

\=> Boolean

| Param \*required | Default | Description                                                                                          |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------------- |
| `date`\*         |         | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object |

### isTomorrow(date)

Tests if date is tomorrow.

\=> Boolean

| Param \*required | Default | Description                                                                                          |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------------- |
| `date`\*         |         | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object |

### isPast(date)

Tests if date is past.

\=> Boolean

| Param \*required | Default | Description                                                                                          |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------------- |
| `date`\*         |         | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object |

### isInLessThan(date, options)

Tests if date is in less than X hours / minutes / seconds.

\=> Boolean

| Param \*required | Default | Description                                                                                          |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------------- |
| `date`\*         |         | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object |
| `options`        | `{}`    |                                                                                                      |
| `hours`          | `0`     | Hours in the future                                                                                  |
| `minutes`        | `0`     | Minutes in the future                                                                                |
| `seconds`        | `0`     | Seconds in the future                                                                                |

### getMonth(index, options)

Returns the month name of a given index.

\=> String

| Param \*required | Default | Description                                           |
| ---------------- | ------- | ----------------------------------------------------- |
| `index`\*        |         | 0-11 index of the month                               |
| `options`        | `{}`    |                                                       |
| `short`          | `false` | Returns the short version of the month — i.e. `"Jan"` |

### getEmailAddresses(conversations)

Returns all the email addresses found in conversations.

\=> Array(AddressField)

| Param \*required  | Default | Description                                          |
| ----------------- | ------- | ---------------------------------------------------- |
| `conversations`\* | `[]`    | Array of [Conversation](#object-Conversation) object |

### getPhoneNumbers(conversations)

Returns all the phone numbers found in conversations.

\=> Array(PhoneField)

| Param \*required  | Default | Description                                          |
| ----------------- | ------- | ---------------------------------------------------- |
| `conversations`\* | `[]`    | Array of [Conversation](#object-Conversation) object |

### formatTimestamp(timestamp, options)

Formats given timestamp.

\=> { date, formatted }

| Param \*required | Default | Description                                                                          |
| ---------------- | ------- | ------------------------------------------------------------------------------------ |
| `timestamp`\*    |         | Unix timestamp in seconds or milliseconds — i.e. `1550586350`                        |
| `options`        | `{}`    |                                                                                      |
| `today`          | `false` | Displays `"Today"` when date is today                                                |
| `tomorrow`       | `false` | Displays `"Tomorrow"` when date is tomorrow                                          |
| `year`           | `false` | Forces the year to be displayed — Year is not displayed by default when current year |
| `time`           | `false` | Displays the hours and minutes                                                       |
| `until`          |         | Unix timestamp — When date spans over multiple days                                  |

### formatDate(string, options)

Formats given date.

\=> { date, formatted }

| Param \*required | Default | Description                                    |
| ---------------- | ------- | ---------------------------------------------- |
| `string`\*       | `""`    | Date string — i.e. `"2018-10-19 17:32:45 GMT"` |
| `options`        | `{}`    | See formatTimestamp options above              |

### formatContact(contact)

Formats given contact.

\=> { letters, formatted }

| Param \*required | Default | Description                                 |
| ---------------- | ------- | ------------------------------------------- |
| `contact`\*      |         | [AddressField](#object-AddressField) object |

### capitalize(string)

Capitalizes given string.

\=> String

| Param \*required | Default | Description              |
| ---------------- | ------- | ------------------------ |
| `string`\*       | `""`    | String to be capitalized |

### classNames(classes)

Converts object to CSS class names.

\=> String

| Param \*required | Default | Description                                                                                    |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------- |
| `classes`\*      | `{}`    | Object of CSS classes definitions and assertions — i.e. `{ foo: true, bar: true, baz: false }` |

### writeToClipboard(text)

Write text to the user’s clipboard.

| Param \*required | Default | Description                     |
| ---------------- | ------- | ------------------------------- |
| `text`           | `""`    | String to copy to the clipboard |

## Events

### main\_action

Triggered when user press the “Integrations main action” shortcut.

\=> ()

### message\_sent

Triggered when a user sends a message, or when a message is scheduled to be sent. Be careful as once triggered, the user can still cancel the delivery of the message within a short period (Undo).

\=> (id)

| Payload | Description                                                                  |
| ------- | ---------------------------------------------------------------------------- |
| `id`    | Use [fetchMessages](#method-fetchMessages) to fetch the data of the message. |

### change:conversations

Triggered when selected conversation(s) change.

\=> (ids)

| Payload | Description                                                                                                                                       |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ids`   | Array of the selected Conversation IDs. Use [fetchConversations](#method-fetchConversations) to fetch the data of newly selected conversation(s). |

### change:users

Triggered when users change.

\=> ()

Use [fetchUsers](#method-fetchUsers) to fetch users data.

## Glossary

### Action

`{ label: 'New task', callback: () => {} }`

`{ label: 'Forward', contexts: ['message'], callback: () => {} }`

| Param \*required | Default  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `contexts`       | `[]`     | Contexts where the action will be available in the Missive UI. Any of `draft, conversations, conversation, message, tel, comment, comment_box, swipe, command_bar, setting` — All when omitted.                                                                                                                                                                                                                                                                                      |
| `label`\*        | `""`     | Action name                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `emoji`          | `""`     | Emoji ID of the emoji used as the action icon in the Missive UI. You can find the ID of a specific emoji on this [page](https://missiveapp.com/open/emoji-mart). For instance, for this 🧹 emoji the ID is `:broom:`.                                                                                                                                                                                                                                                                |
| `swipe_id`       | `""`     | Unique string per swipe action — i.e. `new-task` — *Required for `swipe` context*                                                                                                                                                                                                                                                                                                                                                                                                    |
| `callback`\*     | `null`   | Action callback — Receives an object with either `conversations, conversation, message, tel, comment, comment_box` as keys depending on the context the action was triggered. Callbacks for the `command_bar` context take an `event` object with either a `load, search, execute` type as well as a `messageId`. The callback can be used to send commands that will be displayed in the Command Bar. See the [respondToMessage](#method-respondToMessage) method for more details. |
| `swipe_color`    | `"#aaa"` | Background color of the swipe action                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `layout`         | `"list"` | The layout of the commands inside the Command Bar when using the `command_bar` context. It can be either `list` or `grid`.                                                                                                                                                                                                                                                                                                                                                           |
| `placeholder`    | `""`     | Placeholder of the Command Bar input                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

### AddressField

`{ address: 'frodo@missiveapp.com', name: 'Frodo Baggins' }`

`{ address: 'sam@missiveapp.com' }`

| Param \*required | Default | Description   |
| ---------------- | ------- | ------------- |
| `address`\*      | `""`    | Email address |
| `name`           | `""`    | Contact name  |

### FormField

`{ type: 'input', data: { … }, options: { … } }`

`{ type: 'calendar', data: { … } }`

| Param \*required | Default | Description                                                                                                                                          |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`\*         | `""`    | Field type — Any of `input, textarea, select, calendar, duration, progress, html`                                                                    |
| `scope`          | `{}`    | Dynamically filter out fields not matching this scope — i.e. `{ project_id: 12345 }` — Would only show this field when **project 12345** is selected |
| `data`\*         | `{}`    | Data available for all types — See following `FormField(type:)` for specific types data                                                              |
| `name`\*         | `""`    | Name of the field — As you would normally use inside a `<form>`                                                                                      |
| `value`\*        | `""`    | Default value of the field                                                                                                                           |
| `placeholder`\*  | `""`    | Field placeholder                                                                                                                                    |
| `required`       | `false` | Form won’t submit unless user fills this field                                                                                                       |

FormField(type:input)

| Param \*required | Default | Description                                                        |
| ---------------- | ------- | ------------------------------------------------------------------ |
| `data`           | `{}`    |                                                                    |
| `type`\*         | `{}`    | Input type — Any of `text, number, hidden`                         |
| `focus`          | `false` | Auto focus the input                                               |
| `disabled`       | `false` | Make the input non-editable                                        |
| `precision`      |         | Format number to specific precision — For `number` input type only |
| `options`        | `{}`    |                                                                    |
| `prefix`         | `false` | Make the placeholder always visible                                |
| `thin`           | `false` | Render a smaller input — For `text` input type only                |

FormField(type:textarea)

| Param \*required | Default | Description             |
| ---------------- | ------- | ----------------------- |
| `data`           | `{}`    |                         |
| `rows`           | `4`     | Number of visible rows  |
| `focus`          | `false` | Auto focus the textarea |

FormField(type:select)

| Param \*required | Default | Description                               |
| ---------------- | ------- | ----------------------------------------- |
| `data`           | `{}`    |                                           |
| `value`          |         | Value of the selected option              |
| `options`        | `[]`    | Array of [Option](#object-Option) objects |
| `multiple`       | `false` | Allow selecting multiple options          |

FormField(type:calendar)

| Param \*required | Default                  | Description                                                                  |
| ---------------- | ------------------------ | ---------------------------------------------------------------------------- |
| `data`           | `{}`                     |                                                                              |
| `value`          | `{ timestamp, all_day }` | Unix timestamp and boolean — i.e. `{ timestamp: 1550586350, all_day: true }` |
| `allow_past`     | `false`                  | Allow setting a date in the past                                             |
| `allow_all_day`  | `false`                  | Allow setting a full-day date                                                |

FormField(type:duration)

| Param \*required | Default | Description                     |
| ---------------- | ------- | ------------------------------- |
| `data`           | `{}`    |                                 |
| `value`          | `""`    | HH:MM duration — i.e. `"00:30"` |

FormField(type:progress)

| Param \*required | Default | Description                           |
| ---------------- | ------- | ------------------------------------- |
| `data`           | `{}`    |                                       |
| `value`          |         | Value of the selected step            |
| `steps`          | `[]`    | Array of [Step](#object-Step) objects |

FormField(type:html)

| Param \*required | Default | Description                                                                                                      |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| `data`           | `{}`    |                                                                                                                  |
| `value`          | `""`    | HTML string — i.e. `"<br> <p>Hey <b>there</b>!</p><br> <p>How <span style="color: red">are you</span>?</p><br>"` |

### FormComment

Example:

```javascript
{
  content: 'I will take the Ring, though I do not know the way.',
  authorName: 'Frodo Baggins',
  authorAvatar: 'https://gravatar.com/avatar/014bcc1f9c5920c658a198e6649cd20b',
}
```

| Param \*required | Default | Description                                                      |
| ---------------- | ------- | ---------------------------------------------------------------- |
| `content`\*      | `""`    | Comment body                                                     |
| `authorAvatar`   | `""`    | Author avatar URL                                                |
| `authorName`     | `""`    | Author name                                                      |
| `date`           | `""`    | Date string with format of your choosing — i.e. `"Feb 18, 2019"` |

### FormNote

Examples:

```javascript
{ message: '✓ Completed on Feb 18' }
{ message: 'View on Missive', url: 'https://missiveapp.com' }
```

| Param \*required | Default | Description                         |
| ---------------- | ------- | ----------------------------------- |
| `message`\*      | `""`    | Note body                           |
| `url`            | `""`    | Turn the note into a clickable link |

### FormButton

Examples:

```javascript
{ type: 'cancel', label: 'Cancel' }
{ type: 'submit', label: 'Create' }
```

| Param \*required | Default | Description                           |
| ---------------- | ------- | ------------------------------------- |
| `type`\*         | `""`    | Button type — Any of `submit, cancel` |
| `label`          | `""`    | Button label                          |

### Option

Examples:

```javascript
{ label: 'My Project', value: 12345 }
{ label: 'My Tag', value: 54321, color: '#F00' }
```

| Param \*required | Default  | Description                                         |
| ---------------- | -------- | --------------------------------------------------- |
| `label`\*        | `""`     | Option label                                        |
| `value`\*        | `""`     | Option value                                        |
| `disabled`       | `false`  | Make the option non-clickable                       |
| `color`          | `""`     | Color in HEX format — Add a color pin to the option |
| `colorRadius`    | `"100%"` | Specify the radius of the color pin                 |
| `callback`       | `null`   | Option callback — For `openContextMenu` options     |

### PhoneField

Examples:

```javascript
{ phoneNumber: '+11231231234', name: 'Frodo Baggins' }
{ phoneNumber: '+11231231234' }
```

| Param \*required | Default | Description  |
| ---------------- | ------- | ------------ |
| `phoneNumber`\*  | `""`    | Phone number |
| `name`           | `""`    | Contact name |

### Step

Examples:

```javascript
{ label: 'In Progress', value: 1 }
{ label: 'Completed', value: 2 }
```

| Param \*required | Default | Description |
| ---------------- | ------- | ----------- |
| `label`\*        | `""`    | Step label  |
| `value`\*        | `""`    | Step value  |

***

## Related guides

* [⚙️ Custom Channels](https://missiveapp.com/docs/developers/custom-channels)

Need more specific answers? [Contact us](https://missiveapp.com/docs/developers/contact)
