Add Attachment to a Record

Learn about adding an attachment to an Ironclad Record via the API.

Requirements

  • API Token - learn more about getting your API token here.
  • The ID of the Ironclad Record you want to attach a file to.
  • An attachment key. This is discussed in greater detail below.

Note: This guide and any software contained in it should be used at your own risk by individuals qualified to evaluate its effectiveness. IT IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL IRONCLAD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH YOUR USE OF THIS GUIDE OR ANY SOFTWARE IT CONTAINS.

Your use of the Ironclad API must comply with Ironclad’s API Terms of Use (available at https://legal.ironcladapp.com/api-terms-of-use) and the terms of the Enterprise Services Agreement (or equivalent) entered into between you and Ironclad.

Supported File Extensions

  • .pdf
  • .doc
  • .docx
  • .jpeg
  • .jpg
  • .msg
  • .png
  • .ppt
  • .pptx
  • .tif
  • .xls
  • .xlsx
  • .eml
  • .txt

Steps to Adding an Attachment

Setting Up

This example uses Node.js for adding the attachment to the Ironclad record.

As listed in the requirements section above, you'll need the ID of the Record you want to add the attachment to and an attachment key. The Record ID can be retrieved when you are creating the record or you can be found by querying all records. Additionally, the available attachment keys can be viewed by retrieving the records schema, where the key to use will be one of the keys you choose in the attachments object of the response.

📘

Attachment Keys & API

Note: attachment keys cannot be created via the API at this time.

// Example using .env variable file and `dotenv` library.
require('dotenv').config();

// In this example, we're loading the file locally.
// So, we'll use `readFile`, which is available via
// the `fs/promises` API.
const { readFile } = require('fs/promises');

// Using `axios` to handle API requests.
const axios = require('axios').default;

// Using the `form-data` library to handle 
const FormData = require('form-data');

// Be sure to store your API securely!
const apiToken = process.env.API_TOKEN;

// Your host URL may vary based on the implementation.
const hostUrl = (
  process.env.HOST_URL ? 
  process.env.HOST_URL : 
  'ironcladapp'
);
const apiUrl = `https://${hostUrl}.com/public/api/v1`;

// Example Ironclad Record ID.
const recordId = 'd69bf7cf-f921-472f-91ed-8b01268b49db';

// Example attachment key.
const attachmentKey = 'signedCopy';

Create the FormData

The file must be one of the supported types listed above. We are using the form-data Node.js Library.

// Example function used for retrieving the file data.
const retrieveFile = async () => {
  return await readFile('example-agreement.pdf');
};

// Example creating the FormData where we are passing in
// the file data and a filename.
const createFormData = (fileData, filename) => {
  const formData = new FormData();
  
  // The API requires an `attachment` field, which contains
  // the file data and options.
  formData.append('attachment', fileData, {
    contentType: 'application/pdf',
    filename: `${filename}.pdf`,
  });
  
  // The API also requires a `metadata` filed, containing
  // metadata about the file being added.
  formData.append('metadata', `{"filename": "${filename}.pdf"}`);
  return formData;
};

Call API with FormData

As listed in the requirements section above, you'll need the ID of the Record you want to add the attachment to and an attachment key. The Record ID can be retrieved when you are creating the record or you can be found by querying all records. Additionally, the available attachment keys can be viewed by retrieving the records schema, where the key to use will be one of the keys you choose listed in the attachments object in the response.

// Pass in the form data that is created from above.
const addAttachmentToRecord = async (formData) => {
  // The URL for the API call.
  const createAttachmentUrl = `${apiUrl}/records/${recordId}/attachments/${attachmentKey}`;
  
  // Do a `POST` API call. The `form-data` Node library conveniently
  // provides the needed boundary value for the `Content-Type` header.
  const response = await axios.post(
    createAttachmentUrl,
    formData,
    {
      headers: {
        'Authorization': `Bearer ${apiToken}`,
        'Content-Type': `multipart/form-data; boundary=${formData.getBoundary()}`,
      }
    }
  );
  return response;
};

const createAttachment = async () => {
  const fileData = await retrieveFile();
  const formData = createFormData(fileData, 'my-record-name');
  return await addAttachmentToRecord(formData);
};

createAttachment()
  .then((response) => console.log(response))
  .catch((err) => console.log(err));

Example Code

require('dotenv').config();
const { readFile } = require('fs/promises');
const axios = require('axios').default;
const FormData = require('form-data');

// Be sure to store your API securely!
const apiToken = process.env.API_TOKEN;

// Your host URL may vary based on the implementation.
const hostUrl = (process.env.HOST_URL ? process.env.HOST_URL : 'ironcladapp');
const apiUrl = `https://${hostUrl}.com/public/api/v1`;

const recordId = 'd69bf7cf-f921-472f-91ed-8b01268b49db';
const attachmentKey = 'signedCopy';

const retrieveFile = async () => {
  return await readFile('example-agreement.pdf');
};

const createFormData = (fileData, filename) => {
  const formData = new FormData();
  formData.append('attachment', fileData, {
    contentType: 'application/pdf',
    filename: `${filename}.pdf`,
  });
  formData.append('metadata', `{"filename": "${filename}.pdf"}`);
  return formData;
};

const addAttachmentToRecord = async (formData) => {
  const createAttachmentUrl = `${apiUrl}/records/${recordId}/attachments/${attachmentKey}`;
  const response = await axios.post(
    createAttachmentUrl,
    formData,
    {
      headers: {
        'Authorization': `Bearer ${apiToken}`,
        'Content-Type': `multipart/form-data; boundary=${formData.getBoundary()}`,
      }
    }
  );
  return response;
};

const createAttachment = async () => {
  const fileData = await retrieveFile();
  const formData = createFormData(fileData, 'my-record-name');
  return await addAttachmentToRecord(formData);
};

createAttachment()
  .then((response) => console.log(response))
  .catch((err) => console.log(err));