Custom Metadata
The MASV API allows team admins to create and manage custom metadata forms on portals. When a portal has a form associated with it, a response to that form called "Form Data" is required before a portal package can be created.
Note
Transfer Agent automations do not support Portals with custom metadata forms because it requires interaction with a user to fill out the form.
Delivery formats
Metadata can be delivered in file format and in package upload notification emails.
The following delivery formats are supported:
- json
- csv
- xml
- email_body
Delivery formats are set on the form and multiple formats can be selected at a time.
For formats which generate deliverables in file format, these files are placed in the root of the relevant portal package.
Custom Metadata Workflow
The following steps generalize the custom metadata workflow:
- Team admin creates a form for a portal.
- Team admin updates the form to set form fields.
- User creates a response to this form.
- User creates a package, providing the form response in the create request.
- User completes the upload flow.
- When the user finalizes the package, the metadata for this package is delivered.
Creating a Form
Authorized users can create custom metadata forms for any Portal, subject to their role.
Method | Route |
---|---|
POST | /v1/portals/{{ portal_id }}/form |
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-API-KEY |
String | Yes | API key |
Content-Type | String | Yes | Must be application/json |
BODY
Name | Type | Required | Description |
---|---|---|---|
name | String | Yes | Name of the form to create |
delivery_formats | String[] | Yes | An array of delivery formats for this form. See Delivery Formats for possible values. |
form_template_id | String | No | The ID of the form template this form was based on if it was based on a template. If no form template was used, leave empty. |
fields | Field[] | No | An optional array of fields you wish to create for this form. See Form Fields for information on fields and how they are structured. |
curl -d "{ \"name\": \"$FORM_NAME\", \"delivery_formats\": [\"csv\", \"xml\"], \"form_template_id\": \"$FORM_TEMPLATE_ID\" }" \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X POST https://api.massive.app/v1/portals/$PORTAL_ID/form
Where:
$API_KEY
is a MASV API key$FORM_NAME
is the name you want to give the new form$FORM_TEMPLATE_ID
is the template used to create this form, if one was used. If no template was used, leave blank or omit.$PORTAL_ID
is the ID of the portal on which you are creating this form.
{
"created_at": "2022-02-04T16:51:06.481Z",
"delivery_formats": [
"csv",
"xml"
],
"fields": [],
"id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"name": "Test Form",
"disabled": false,
"owner_id": "portal-01FV2TAXEJ7DVRX2WQ0W5Y4QA0",
"team_id": "01FTVJSKRAGV1MBV2PSF0GHVVP",
"updated_at": "2022-02-04T16:51:06.481Z"
}
Form Fields
Form fields have the following properties:
Property | Type | Description |
---|---|---|
name | String | The name of this field. Must be unique for this form. This field is not shown to users. |
label | String | The label which will be shown to users |
type | Enum | The input type of this field. Possible values: checkbox radio dropdown date short_text long_text number url email package_name package_description sender_email |
visibility | Enum | The visibility of this field. Possible values: required optional readonly hidden |
default_value | String | The default value of this field. |
position | Integer | The position in which this field will be rendered relative to other fields. Fields are ordered in ascending order based on this property. |
options | String[] | A list of options for use by external frontend applications. If options are provided, default_value must be within the options array. Options is supported for the following field types: checkbox , radio , dropdown . If provided for any other field type, it will be ignored. |
There are also the following additional fields which are system generated: id
created_at
updated_at
form_id
Form fields are set by updating the form object.
Special Field Types
Fields of type package_name
package_description
and sender_email
are used in the package creation process.
There can only be one field of each of these types in a form.
For example, creating a package with a form response which contains a field of type package_name
will be the value of that field as the new package's name.
Updating Forms
Authorized users can update forms which belong to any portal they are an admin on.
Method | Route |
---|---|
PUT | /v1/metadata/forms/{{ form_id }} |
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-API-KEY |
String | Yes | API key |
Content-Type | String | Yes | Must be application/json |
BODY
When updating forms, you should always pass in the full form object including any modifications you wish to make. The following table outlines fields which will be updated to match the values you provided.
Name | Type | Description |
---|---|---|
name | String | The form's name |
delivery_formats | String | The delivery formats of this form. Possible values: json csv xml email_body |
disabled | Boolean | If this is true, the form is disabled. |
fields | FormField[] | An array of form fields. See the above Form Fields section for more info on form fields. |
curl -d "{ \"name\": \"$NEW_NAME\", \"delivery_formats\": [$NEW_DELIVERY_METHODS], \"disabled\": false, \"fields\": $NEW_FIELD_ARRAY }" \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X PUT https://api.massive.app/v1/metadata/forms/$FORM_ID
EXAMPLE
{
"name": "Test Form",
"delivery_formats": [
"json", "csv", "xml", "email_body"
],
"disabled": false,
"fields": [
{
"name": "uploader_name",
"label": "Name",
"type": "short_text",
"visibility": "required",
"position": 1
},
{
"name": "description",
"label": "Package Description",
"type": "package_description",
"visibility": "optional",
"position": 2
},
{
"name": "name",
"label": "Package Name",
"type": "package_name",
"visibility": "optional",
"position": 3
},
{
"name": "sender_email",
"label": "Sender Email",
"type": "sender_email",
"visibility": "optional",
"position": 4
}
]
}
{
"created_at": "2022-02-04T16:51:06.481Z",
"delivery_formats": [
"json",
"csv",
"xml",
"email_body"
],
"fields": [
{
"created_at": "2022-02-04T19:07:09.104Z",
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV3244XGC7PQJ509K49R8RTZ",
"label": "Sender Email",
"name": "sender_email",
"position": 4,
"type": "sender_email",
"updated_at": "2022-02-04T19:07:09.104Z",
"visibility": "optional"
},
{
"created_at": "2022-02-04T19:07:09.104Z",
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV3244XG2Y5WPTPKXDY5V1CD",
"label": "Name",
"name": "uploader_name",
"position": 1,
"type": "short_text",
"updated_at": "2022-02-04T19:07:09.104Z",
"visibility": "required"
},
{
"created_at": "2022-02-04T19:07:09.104Z",
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV3244XGEAJY2NBH57MWTG55",
"label": "Package Description",
"name": "description",
"position": 2,
"type": "package_description",
"updated_at": "2022-02-04T19:07:09.104Z",
"visibility": "optional"
},
{
"created_at": "2022-02-04T19:07:09.104Z",
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV3244XGF0M0DQ26R5MZFBVE",
"label": "Package Name",
"name": "name",
"position": 3,
"type": "package_name",
"updated_at": "2022-02-04T19:07:09.104Z",
"visibility": "optional"
}
],
"id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"name": "Test Form",
"owner_id": "portal-01FV2TAXEJ7DVRX2WQ0W5Y4QA0",
"team_id": "01FTVJSKRAGV1MBV2PSF0GHVVP",
"updated_at": "2022-02-04T19:07:09.101Z"
}
Setting Form Fields
To set a form's fields, you use the Update Form endpoint described in the above section Updating Forms
and provide the form's new set of fields under the fields
bode property.
Warning
When a form's fields are updated, the old fields are fully replaced.
Submitting a Form Response
When submitting a form response, the only validation performed is on required fields. If a required field is missing a value in the request body, an error will be returned. Any data you pass in will be recorded as it is provided.
Authorized users with permission to create portal packages can create responses for a portal's current form.
Method | Route |
---|---|
POST | /v1/portals/{{ portal_id }}/forms/responses |
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-API-KEY | String | * | API key |
X-Access-Code | String | * | The portal's access code |
Content-Type | String | Yes | Must be application/json |
Either X-API-KEY
or X-Access-Code
is required
BODY
The body consists of a JSON object containing key/value pairs for each field. The key is the form's name, the value is an object containing a "value" property. The value of the "value" property should be the data you're submitting in string form. See the example request body below.
curl -d "{ \"$KEY1\": { \"value\": \"$VALUE1\" }, OTHER_PAIRS... }" \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X POST https://api.massive.app/v1/portals/$PORTAL_ID/form/responses
EXAMPLE
{
"uploader_name": {
"value": "Example uploader name"
},
"description": {
"value": "Example package description"
},
"name": {
"value": "Example package name"
},
"sender_email": {
"value": "[email protected]"
}
}
{
"created_at": "2022-02-04T19:33:33.623Z",
"delivery_formats": [
"json",
"csv",
"xml",
"email_body"
],
"fields": [
{
"created_at": "2022-02-04T19:33:33.625Z",
"field_id": "01FV3244XGEAJY2NBH57MWTG55",
"form_data_id": "01FV33MG9Q56YJG1J74GPS3KD2",
"id": "01FV33MG9SB9KKDZY4H397ERJ6",
"label": "Package Description",
"name": "description",
"position": 2,
"type": "package_description",
"updated_at": "2022-02-04T19:33:33.625Z",
"value": "Example package description",
"visibility": "optional"
},
{
"created_at": "2022-02-04T19:33:33.625Z",
"field_id": "01FV3244XGF0M0DQ26R5MZFBVE",
"form_data_id": "01FV33MG9Q56YJG1J74GPS3KD2",
"id": "01FV33MG9SY17TVHZN0QH1P0F9",
"label": "Package Name",
"name": "name",
"position": 3,
"type": "package_name",
"updated_at": "2022-02-04T19:33:33.625Z",
"value": "Example package name",
"visibility": "optional"
},
{
"created_at": "2022-02-04T19:33:33.625Z",
"field_id": "01FV3244XGC7PQJ509K49R8RTZ",
"form_data_id": "01FV33MG9Q56YJG1J74GPS3KD2",
"id": "01FV33MG9S37XH4HJ4AARWFG7K",
"label": "Sender Email",
"name": "sender_email",
"position": 4,
"type": "sender_email",
"updated_at": "2022-02-04T19:33:33.625Z",
"value": "[email protected]",
"visibility": "optional"
},
{
"created_at": "2022-02-04T19:33:33.625Z",
"field_id": "01FV3244XG2Y5WPTPKXDY5V1CD",
"form_data_id": "01FV33MG9Q56YJG1J74GPS3KD2",
"id": "01FV33MG9SJCG9VQ7B2ZMJRY6Z",
"label": "Name",
"name": "uploader_name",
"position": 1,
"type": "short_text",
"updated_at": "2022-02-04T19:33:33.625Z",
"value": "Example uploader name",
"visibility": "required"
}
],
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV33MG9Q56YJG1J74GPS3KD2",
"name": "Test Form",
"owner_id": "portal-01FV2TAXEJ7DVRX2WQ0W5Y4QA0",
"package_id": "placeholder",
"team_id": "01FTVJSKRAGV1MBV2PSF0GHVVP",
"updated_at": "2022-02-04T19:33:33.623Z"
}
Using Form Responses
To attach a form response to a new portal package, add the form response's ID to the create portal package body under the key form_data_id
.
This will bind a form response to the new package. Additionally, the values of any special fields
will be used in the package creation process.
To see how to create a portal package, see Create a package.
Getting Package Metadata
Authorized users with a full-access package token can fetch a package's custom metadata.
Method | Route |
---|---|
GET | /v1/packages/{{ package_id }}/metadata |
Info
To get a full access package token, use the List Portal Packages endpoint with new=1
, and use the resulting access_token
of the target package as the package token in this request.
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-Package-Token | String | * | Full-Access package JSON Web Token |
curl -H "X-Package-Token: $PACKAGE_TOKEN" \
-X GET https://api.massive.app/v1/packages/$PACKAGE_ID/metadata
EXAMPLE
{
"created_at": "2022-02-04T18:59:16.232Z",
"delivery_formats": [
"json",
"csv",
"xml",
"email_body"
],
"fields": [
{
"created_at": "2022-02-04T18:59:16.234Z",
"field_id": "01FV304N2S8TGWZ43F6N44J9DZ",
"form_data_id": "01FV31NQ486PPGJE0JDVBZE6PR",
"id": "01FV31NQ4A3HWWQXC36ARCHWXM",
"label": "Name",
"name": "uploader_name",
"position": 1,
"type": "short_text",
"updated_at": "2022-02-04T13:59:16.235Z",
"value": "username",
"visibility": "required"
},
{
"created_at": "2022-02-04T18:59:16.234Z",
"field_id": "01FV304N2S8AJ8NVVKMSCE5Y20",
"form_data_id": "01FV31NQ486PPGJE0JDVBZE6PR",
"id": "01FV31NQ4A93CKE6ZN2F11RRJC",
"label": "Package Description",
"name": "description",
"position": 2,
"type": "package_description",
"updated_at": "2022-02-04T13:59:16.234Z",
"value": "Example package description",
"visibility": "optional"
},
{
"created_at": "2022-02-04T18:59:16.234Z",
"field_id": "01FV304N2S0CM38P0ATT27Q5BH",
"form_data_id": "01FV31NQ486PPGJE0JDVBZE6PR",
"id": "01FV31NQ4AW20WPJHGEVFETV5C",
"label": "Package Name",
"name": "name",
"position": 3,
"type": "package_name",
"updated_at": "2022-02-04T13:59:16.234Z",
"value": "Example package name",
"visibility": "optional"
},
{
"created_at": "2022-02-04T18:59:16.234Z",
"field_id": "01FV304N2S4TQGVSW5HWT7QD0X",
"form_data_id": "01FV31NQ486PPGJE0JDVBZE6PR",
"id": "01FV31NQ4A9Q5RMYBY5DBMJPTE",
"label": "Sender Email",
"name": "sender_email",
"position": 4,
"type": "sender_email",
"updated_at": "2022-02-04T13:59:16.235Z",
"value": "[email protected]",
"visibility": "optional"
}
],
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV31NQ486PPGJE0JDVBZE6PR",
"name": "Test Form",
"owner_id": "portal-01FV2TAXEJ7DVRX2WQ0W5Y4QA0",
"package_id": "01FV31NS5J98H69K9JT2G8QP33",
"team_id": "01FTVJSKRAGV1MBV2PSF0GHVVP",
"updated_at": "2022-02-04T13:59:18.324Z"
}
Getting Portal Metadata Fields
To get the fields required to create a portal form response, you use the Get Portal endpoint. If it has a form requirement, an array of form fields will be returned.
Authorized users with a full-access package token can fetch a portal's details, including metadata fields.
Metadata fields are returned in array form under custom_metadata
and are sorted ascendingly by their position field.
Method | Route |
---|---|
GET | /v1/portals/{{ portal_id }} |
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-API-KEY | String | * | API key |
X-Access-Code | String | * | A portal's access code |
Either X-API-KEY
or X-Access-Code
are required.
curl -H "X-API-KEY: $API_KEY" \
-X GET https://api.massive.app/v1/portals/$PORTAL_ID
EXAMPLE
{
"active": true,
"cloud_connections": [],
"created_at": "2022-02-04T16:51:02.226Z",
"custom_metadata": [
{
"label": "Sender Email",
"name": "sender_email",
"position": 4,
"type": "sender_email",
"visibility": "optional"
},
{
"label": "Package Name",
"name": "name",
"position": 3,
"type": "package_name",
"visibility": "optional"
},
{
"label": "Package Description",
"name": "description",
"position": 2,
"type": "package_description",
"visibility": "optional"
},
{
"label": "Name",
"name": "uploader_name",
"position": 1,
"type": "short_text",
"visibility": "required"
}
],
"custom_webhooks": [],
"disable_upload_receipt": false,
"has_access_code": false,
"has_download_password": false,
"id": "01FV2TAXEJ7DVRX2WQ0W5Y4QA0",
"name": "Example portal",
"primary_color": "#ABCABC",
"recipients": null,
"subdomain": "portalsubdomain",
"updated_at": "2022-02-04T11:51:02.226Z"
}
Deleting Forms
Authorized users can delete custom metadata forms.
Method | Route |
---|---|
DELETE | /v1/metadata/forms/{{ form_id }} |
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-API-KEY | String | Yes | API key |
BODY
No body.
curl -H "X-API-KEY: $API_KEY" \
-X DELETE https://api.massive.app/v1/metadata/forms/$FORM_ID
RESPONSE
Status Code 204: No Content
Creating a Form Template
Authorized users can create custom metadata form templates for their team.
Form Templates almost directly mirror Forms.
Method | Route |
---|---|
POST | /v1/teams/{{ team_id }}/forms/templates |
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-API-KEY | String | Yes | API key |
Content-Type | String | Yes | Must be application/json |
BODY
Name | Type | Required | Description |
---|---|---|---|
name | String | Yes | Name of the form to create |
delivery_formats | String[] | Yes | An array of delivery formats for this form. See Delivery Formats for possible values. |
curl -d "{ \"name\": \"$FORM_TEMPLATE_NAME\", \"delivery_formats\": [\"csv\", \"xml\"] }" \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X POST https://api.massive.app/v1/teams/$TEAM_ID/forms/templates
Where:
$API_KEY
is a MASV API key.$FORM_TEMPLATE_NAME
is the name you want to give the new form$TEAM_ID
is the ID of the team on which you are creating this form template.
{
"created_at": "2022-01-25T19:12:28.423Z",
"delivery_formats": [
"csv",
"xml"
],
"id": "01FT9AEPR7YCAF0MTR6SC5ETRH",
"name": "Test Template",
"team_id": "01FT994WS8BAGDNQFS627Q69R6",
"updated_at": "2022-01-25T19:12:28.423Z"
}
Updating Form Templates
Authorized users can update form templates which belong to their team.
Method | Route |
---|---|
PUT | /v1/metadata/forms/templates/{{ form_template_id }} |
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-API-KEY | String | Yes | API key |
Content-Type | String | Yes | Must be application/json |
BODY
When updating form templates, you should always pass in the full form template object including any modifications you wish to make. The following table outlines fields which will be updated to match the values you provided.
Name | Type | Description |
---|---|---|
name | String | The form's name |
delivery_formats | String | The delivery formats of this form. Possible values: json csv xml email_body |
fields | FormField[] | An array of form fields. See the above Form Fields section for more info on form fields. |
curl -d "{ \"name\": \"$NEW_NAME", \"delivery_formats\": $NEW_DELIVERY_METHOD_ARRAY, \"disabled\": false, \"fields\": $NEW_FIELD_ARRAY }" \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X PUT https://api.massive.app/v1/metadata/forms/templates/$FORM_TEMPLATE_ID
EXAMPLE
{
"name": "Test Form Template",
"delivery_formats": [
"json", "csv", "xml", "email_body"
],
"fields": [
{
"name": "uploader_name",
"label": "Name",
"type": "short_text",
"visibility": "required",
"position": 1
},
{
"name": "description",
"label": "Package Description",
"type": "package_description",
"visibility": "optional",
"position": 2
},
{
"name": "name",
"label": "Package Name",
"type": "package_name",
"visibility": "optional",
"position": 3
},
{
"name": "sender_email",
"label": "Sender Email",
"type": "sender_email",
"visibility": "optional",
"position": 4
}
]
}
{
"created_at": "2022-02-04T16:51:06.481Z",
"delivery_formats": [
"json",
"csv",
"xml",
"email_body"
],
"fields": [
{
"created_at": "2022-02-04T19:07:09.104Z",
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV3244XGC7PQJ509K49R8RTZ",
"label": "Sender Email",
"name": "sender_email",
"position": 4,
"type": "sender_email",
"updated_at": "2022-02-04T19:07:09.104Z",
"visibility": "optional"
},
{
"created_at": "2022-02-04T19:07:09.104Z",
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV3244XG2Y5WPTPKXDY5V1CD",
"label": "Name",
"name": "uploader_name",
"position": 1,
"type": "short_text",
"updated_at": "2022-02-04T19:07:09.104Z",
"visibility": "required"
},
{
"created_at": "2022-02-04T19:07:09.104Z",
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV3244XGEAJY2NBH57MWTG55",
"label": "Package Description",
"name": "description",
"position": 2,
"type": "package_description",
"updated_at": "2022-02-04T19:07:09.104Z",
"visibility": "optional"
},
{
"created_at": "2022-02-04T19:07:09.104Z",
"form_id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"id": "01FV3244XGF0M0DQ26R5MZFBVE",
"label": "Package Name",
"name": "name",
"position": 3,
"type": "package_name",
"updated_at": "2022-02-04T19:07:09.104Z",
"visibility": "optional"
}
],
"id": "01FV2TB1KHRFQJ76MEWPKDX2G9",
"name": "Test Form Template",
"owner_id": "portal-01FV2TAXEJ7DVRX2WQ0W5Y4QA0",
"team_id": "01FTVJSKRAGV1MBV2PSF0GHVVP",
"updated_at": "2022-02-04T19:07:09.101Z"
}
Deleting Form Templates
Authorized users can delete custom metadata form templates.
Method | Route |
---|---|
DELETE | /v1/metadata/forms/templates/{{ form_template_id }} |
HEADERS
Name | Type | Required | Description |
---|---|---|---|
X-API-KEY | String | Yes | API key |
BODY
No body.
curl -H "X-API-KEY: $API_KEY" \
-X DELETE https://api.massive.app/v1/metadata/forms/templates/$FORM_TEMPLATE_ID
RESPONSE
Status Code 204: No Content