Affinity

Affinity

Introduction

Welcome to Affinity API v2! This API provides a RESTful interface for building internal apps, automated workflows, and other integrations on top of the core data models in Affinity, and for connecting Affinity to the rest of your tech and data stack.

Please note that this new version of the API is not at feature parity with Affinity API v1. We will add to this new version to cover more of v1's functionality over time. This API version is also only available on select Affinity license types. See this Help Center article or contact your Customer Success Manager for more information.

Getting Started

All Affinity API endpoints use the base URL https://api.affinity.co. All v2 endpoint paths start with /v2. Requests must be sent over HTTPS.

Using These Docs

The first few sections of these docs cover general information on the API. Each subsequent section covers a set of API endpoints.

Each endpoint is documented with its accepted request parameters, expected response shapes, and a sample request and response. Please note that the shape of a given response can vary depending on what "type" of object or data is being returned. When this is the case, the response documentation will include a dropdown that can be used to select the "type" for which to display the response shape.

Authentication

Affinity API v2 uses API keys and bearer authentication (this is an important difference from Affinity API v1's use of basic authentication).

To generate an API key, navigate to the Settings page in the Affinity web app. You will need the "Generate an API key" role-based permission controlled by your Affinity admin to be able to do this. See this Help Center article for full instructions on API key generation, and this article for more information on role-based permissions in Affinity.

Currently, we support one API key per user in your Affinity account. Your API key is able to read data and perform actions in Affinity on your behalf, so keep it safe as you would a password.

Provide your API key as your bearer authentication token to start making calls to Affinity API v2.

Permissions

Overall requirements

You must have the "Generate an API key" permission to be able to work with the Affinity API. Most users in most Affinity accounts with API access have this by default — Contact your Affinity admin if you are not able to generate an API key, and see this article for more information on role-based permissions in Affinity.

Resource-level permissions

The Affinity API respects sharing permissions that are set in-product. For example, if a given user does not have access to a list, note, or interaction in-product, they will not be able to see or modify it via API.

Endpoint-level permissions

Many API endpoints also require endpoint-specific permissions that map to permissions in-product. These permissions, along with the "Generate an API key" permission, are managed by your Affinity admin in the Settings page:

API v2 EndpointRequired Permission
GET /v2/companies"Export All Organizations directory"
GET /v2/companies/{id}"Export All Organizations directory"
GET /v2/companies/{id}/list-entries"Export data from Lists"
GET /v2/persons"Export All People directory"
GET /v2/persons/{id}"Export All People directory"
GET /v2/persons/{id}/list-entries"Export data from Lists"
GET /v2/opportunities"Export data from Lists"
GET /v2/opportunities/{id}"Export data from Lists"
GET /v2/lists/{listId}/list-entries"Export data from Lists"
GET /v2/lists/{listId}/saved-views/{viewId}/list-entries"Export data from Lists"

Rate Limits

The Affinity API sets a limit on the number of calls that a user can make per minute, and that all the users on an account can make per month. It also sets a reasonable limit on the number of concurrent requests it will support from an account at one time.

Requests to both Affinity API versions will count toward the one pool of requests allowed for a user or account. Once a per-minute, monthly, or concurrent rate limit is hit, subsequent requests will return an error code of 429. We highly recommend designing your application to handle 429 errors.

Per-Minute Limits (User-Level)

To help protect our systems, API requests will be halted at 900 per user, per minute. We may also lower this limit on a temporary basis to manage API availability.

Concurrent Request Limits (Account-Level)

To protect our systems and manage availability across customers, we set a reasonable limit on concurrent requests at the account level. Customers should not expect to hit this limit unless they are hitting the API with heavy operations from many concurrent threads at once.

Monthly Plan Tier Limits (Account-Level)

The overall number of requests you can make per month will depend on your account's plan tier. This monthly account-level limit resets at the end of each calendar month. Current rate limits by plan tier are:

Plan TierCalls Per Month
EssentialsNone
Scale100k
Advanced100k
EnterpriseUnlimited*

*Per-Minute and Concurrent Request Limits still apply.

Rate Limit Headers

All API calls will return the following response headers with information about per-minute and monthly limits:

HeaderDescription
X-Ratelimit-Limit-UserNumber of requests allowed per minute for the user
X-Ratelimit-Limit-User-RemainingNumber of requests remaining for the user
X-Ratelimit-Limit-User-ResetTime in seconds before the limit resets for the user
X-Ratelimit-Limit-OrgNumber of requests allowed per month for the account
X-Ratelimit-Limit-Org-RemainingNumber of requests remaining for the account
X-Ratelimit-Limit-Org-ResetTime in seconds before the limit resets for the account

Pagination

When an endpoint is expected to return multiple results, we break the results up into pages to make them easier to handle. To cycle forward through multiple pages of data, look for the nextUrl property in the pagination portion of an API response, and use it for your next request. See endpoint documentation for more information.

Error Codes

Here is a list of the error codes this API will generally return if something goes wrong (see endpoint documentation for endpoint-specific error information):

Error CodeMeaning
400Bad Request — See endpoint documentation for more information.
401Unauthorized — Your API key is invalid.
403Forbidden — Insufficient rights to a resource.
404Not Found — Requested resource does not exist. See endpoint documentation for more information.
405Method Not Allowed — The method being used is not supported for this resource.
422Unprocessable Entity — Malformed parameters supplied. This can also happen in cases the parameters supplied logically cannot complete the request. In this case, an appropriate error message is delivered.
429Too Many Requests — You have exceeded the rate limit.
500Internal Server Error — We had a problem with our server. Try again later.
503Service Unavailable — This shouldn't generally happen. Contact us if you encounter this error.

Data Model

The Basics

Working with Field Data

Field Types and IDs

There are a few types of Fields in Affinity, differentiated by the scope and source of their data:

Field TypeDescriptionExample FieldsField ID Pattern
enrichedFirmographic, funding, and people Fields populated by Affinity. These can be "Affinity Data" Fields or come from distinct data partners."Affinity Data: Description", "Dealroom: Number of Employees"A string representing the enrichment source, followed by the field name, e.g. affinity-data-description or dealroom-number-of-employees.
listFields that are specific to the context of a given list. These can only be accessed through */list-entries endpoints in this version of the API.Default "Status" and "Amount" columns, custom columns that pertain to a given List of deals or foundersfield-, followed by a unique integer, e.g. field-1234
globalFields that persist across an Affinity account and are not list-specific."My Firm's Founder Scoring Column"field-, followed by a unique integer, e.g. field-1234
relationship-intelligenceFields populated by Affinity from users' email and calendar data that provide insight into your firm's relationship with a given Person/Company/Opportunity."Source of Introduction", "First Email", "Last Email", "First Event", "Last Event", "Next Event", "First Chat Message", "Last Chat Message", "Last Contact"A string similar to the field's name in-product, e.g. source-of-introduction

Field Value Types

Field data can take a variety of shapes. These value types are described in the Affinity Help Center here. Here is a list of the same value types, as represented in this API. Notice how array types end with -multi:

Single TypeArray Type
textNot supported in Affinity
numbernumber-multi
datetimeNot supported in Affinity
locationlocation-multi
dropdowndropdown-multi
ranked-dropdownNot supported in Affinity
personperson-multi
companycompany-multi
filterable-text*filterable-text-multi*

*Please note that filterable-text and filterable-text-multi are special types that operate similarly to dropdown and dropdown-multi. They are reserved for Affinity-populated Fields, and users cannot create Fields with these types.

When an array-typed value has no data in it, the API will return null (rather than an empty array).

Retrieving Field Data

To retrieve field data on companies, persons, or opportunities, call GET /v2/companies, GET /v2/persons, or one of our GET */list-entries endpoints. (Note that Opportunities only have list-specific Fields, so all their field data will live on the */list-entries endpoints.) For most of these endpoints, you will need to specify the Fields for which you want data returned via the fieldIds or fieldTypes parameter — Otherwise, entities will be returned without any field data attached.

The GET /v2/companies and /v2/persons endpoints can return entities with enriched, global, and relationship intelligence field data attached, but do not support list-specific field data. To get comprehensive field data including list-specific field data on Companies and Persons, use the GET */list-entries endpoints.

Specifying Desired Fields (Field Selection)

As mentioned above, you will need to specify the Fields (either by ID or by Type) for which you want data returned when using the following endpoints:

Each of these endpoints has a fieldIds parameter that accepts an array of Field IDs, and a fieldTypes parameter that accepts an array of Field Types. Use the GET */fields endpoints to get Field IDs, Field Types, and other Field-level metadata:

The following endpoints don't require field selection:

Saved Views

A Saved View allows a user to configure the Fields they want to see in the UI for a given List, and set filters and sorts on the rows on that List. A List can have multiple Saved Views. In the context of this API, Saved Views can be useful for specifying the exact Fields for which data is needed. The */saved-views/{viewId}/list-entries endpoint also respects the filters that have been set on the given Saved View in the Affinity web app. (It does not, however, respect sorts just yet.)

Partner Data Restrictions

This API supports pulling data from Affinity Data fields and select Dealroom fields. Due the agreements we have with some of our data partners, the API does not expose data from the following sources:

A Note on Nested Associations

Some GET endpoints return "association" data under fields. For example, the Persons GET endpoints return data about which Companies a Person is associated with in Affinity. The Opportunities GET endpoints return similar data about associated Companies and Persons. The List Entries GET endpoints also return this data for Person and Opportunity List Entries.

The API truncates these nested arrays of Persons or Companies at 100 entries. For example, if an Opportunity is associated with 200 Persons in Affinity, only 100 of those Persons will be returned by the GET /opportunities or /opportunities/{id} endpoint.

User Guides

A Tour of Our GET Endpoints

Desired DataRelevant EndpointsNotes
Company/Person/Opportunity rows from a ListGrab the List’s ID from its URL in the Affinity web app, then hit GET /v2/lists/{listId}/list-entriesData returned will be restricted to the rows on the requested List
Company/Person/Opportunity rows from a Saved ViewIn the Affinity web app, navigate to a List and create a Saved View with the desired field data and filters on it. Grab the List and Saved View IDs from the web app URL, then hit GET /v2/lists/{listId}/saved-views/{viewId}/list-entriesData returned will be restricted to the rows and columns on the requested Saved View
Full rolodex of Companies or Persons in AffinityGET /v2/companies, GET /v2/personsData from list-specific Fields will not be returned
All the rows for a given Company or Person across all ListsGET /v2/companies/{id}/list-entries, GET /v2/persons/{id}/list-entries
Metadata on Fields, including Field IDsGET /v2/companies/fields, GET /v2/persons/fields, GET /v2/lists/{listId}/fieldsMetadata on list-specific Fields will only be returned by GET /v2/lists/{listId}/fields
Metadata on Lists or Saved ViewsGET /v2/lists, GET /v2/lists/{listId}/saved-views
Opportunity dataGET /v2/opportunities will only return Opportunity names and List IDs. For comprehensive Opportunity data, hit GET /v2/lists/{listId}/list-entries for an Opportunity List

Tip: The ID for a List, Saved View, Person, Company, or Opportunity can always be found in its Affinity web app URL.

Changelog

March 25, 2024

January 4, 2023

December 12, 2023

Operations

Get current user
Get metadata on Company Fields
Get all Companies
Get a single Company
Get a Company's List Entries
Get a Company's Lists
Get metadata on all Lists
Get metadata on a single List's Fields
Get metadata on a single List
Get all List Entries on a List
Get metadata on Saved Views
Get metadata on a single Saved View
Get all List Entries on a Saved View
Get all Opportunities
Get a single Opportunity
Get metadata on Person Fields
Get all Persons
Get a single Person
Get a Person's List Entries
Get a Person's Lists