Overview

Investor Management API

Overview

The AngelList API is a GraphQL API for working with Transactions. The GraphQL API is self-documenting, and you can explore the schema via introspection. With the API, you can perform actions such as:

  • Inspecting an existing transaction for status and metadata information
  • Receiving a callback when a Transaction is complete

Get the API key

To access AngelList's GraphQL API, you need an API key. Please submit a request to the AngelList team with the following information:

  1. Your organization handle
  2. For which environment do you need the key (staging or production)
  3. The email(s) of the users at your organization who will retrieve the key

Upon receipt of the information above, the AngelList team will create the API key and then share the key with you via a secure link that is only available to the email(s) you provided. The link will expire within one hour.

  • The API key should have the prefix sk_test if you are using the staging environment or sk_live if you are using the production environment.

Note, you cannot use the staging key for the production environment. If you want to enable integration with the production environment, please send a separate request for a different key.

Make an API request

The AngelList Investor Management API endpoint is https://portal-api-staging.angellist.com/betafor our staging environment and https://portal-api.angellist.com/beta for our production environment.

The AngelList Investor Management API uses the API key to authenticate requests. Authentication to the API is performed via bearer auth. For example, you can pass your staging API key in via the following header like this:

{
  "Authorization": "Bearer sk_test_pmdmbyadq5a17raxfubz8sit"
}

All API requests must be made over HTTPS. Calls made over plain HTTP will fail.

GraphQL Schema

The best way to explore the self-documenting API schema is to use our GraphQL API Explorer 🚀

Here are some explanations for the not-so-obvious types in the Schema.

FieldDescription
scalar datetimeA date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the date-time format outlined in section 5.6 of the RFC 3339 profile of the ISO8601 standard for representation of dates and times using the Gregorian calendar.
scalar JSONThe JSON scalar type represents JSON values as specified by ECMA-404.
scalar uuidThe UUID scalar type represents UUID values as specified by RFC 4122.

Commonly used fields

The fields below are the most commonly used part of the schema by our API customers today.

type Query {
  entity(id: uuid!): Entity
  organization(id: uuid!): Organization
  transaction(id: uuid!): Transaction
  transactionItem(id: uuid!): TransactionItem
  transactionFile(id: uuid!): TransactionFile
  transactionSignatureFile(id: uuid!): TransactionSignatureFile
  transactionRecipient(id: uuid!): TransactionRecipient
}

Fetching transaction data

One of the most common reasons to use our API is to fetch additional transaction data after receiving a webhook request. The example request below returns information about transaction recipients and transaction processes (commonly needed for most API integrations we see).

Note that every revision of a transaction process creates a new transactionProcessRevision with a new set of transactionItems (so that existing data is preserved for audit reasons). The top level transactionItems field will always return all items, including ones from previous revisions, which means you'll have to sort the output of transactionItems by transactionItem.createdAt -> desc to get the latest data.

A different pattern is querying for items through transactionProcessRevisions instead of the transactionItems field. You'll still need to sort by transactionProcessRevisions.createdAt -> desc, but you'll also get revision data within your response which gives more context and structure to the underlying item data.

query TransactionProcessData($id: uuid!) {
  transaction(id: $id) {
    id
    transactionRecipients {
      id
      vulcanKey
      entity {
        id
        name
        email
        settings
        type
      }
    }
    transactionProcessRevisions {
      id
      transactionProcessId
      createdAt
      committedAt
      context
      transactionItems {
        id
        completionPercentage
        createdAt
        data
        vulcanKey
      }
    }
  }
}

Creating a transaction

The createTransaction mutation is used to create a new transaction. Some of the required input fields like the templateId, senderEntityId can be retrieved by making queries to the graph.

input CreateTransactionInput {
  inputData: json
  noticeEmail: String!
  noticeName: String!
  senderEntityId: uuid!
  templateId: uuid!
}

type CreateTransactionPayload {
 transactionId: uuid!
 transmitToken: uuid! 
}

type Mutation {
  
 	createTransaction(
    input: CreateTransactionInput!
  ): CreateTransactionPayload!

}

Completing a transaction

A transaction is complete once all processes are complete. Note that a transaction configuration can specify configurations for processes that may never be created. Completion is calculated by iterating through all processes in the database and checking if they are complete.

  • TransactionRecipient: A Transaction Recipient encapsulates an entity that is privy to a transaction. A transaction recipient can be part of multiple processes. Most transactions have one recipient, but some have two if the sender needs to countersign a document at the end.
  • TransactionProcess: A process encapsulates a set of Items (forms) and Signatures that need to be done for a transaction. Most transactions only have one process. You may have multiple processes if your workflow is complicated— we'll tell you if this is the case.
  • TransactionFile: A file represents a point to a file object uploaded by a recipient. To download this file, you will need to use the genTransactionFileLink mutation to create a signed link that you can then use to download the document.
  • TransactionSignature: A signature represents a single signature for a document within the AngelList platform. Typically, documents will have multiple signatures. The global state across these signatures is managed by the TransactionSignatureContainer structure below.
  • TransactionSignatureContainer: A signature container manages the global state across signatures.
  • TransactionSignatureFile: A signature file represents a file that has been signed. These are typically generated documents based on the data entered in by a recipient.
type File {
  id: UUID!
  mimeType: String!
  extension: String!
  originalFilename: String!
  overrideFilename: String
  createdAt: DateTime!
  uploadedAt: DateTime
  signedUrl: String!
}

type Query { 
  file(id: UUID!): File!
}

Triggering an event to move the transaction state forward

Transaction state transitions occur when there is an event, generally triggered in the AngelList UI.

In rare occasions, you will need to move a transaction state forward manually using the API.

You can use this mutation to trigger an event using the API to cause a state transition.

input TriggerTransactionEventInput {
  transactionId: UUID!
  eventKey: String!
}
  
type TriggerTransactionEventPayload {
  sourceStateKey: String
  targetStateKey: String!
}

type Mutation {
  triggerTransactionEvent(
    input: TriggerTransactionEventInput!  
  ): TriggerTransactionEventPayload!
}

The eventKey in the input can be found in the workflow FSM configuration.

Please reach out to AngelList support if you need help identifying the event key.