API Reference

Upscale APIs for personalised LinkedIn outreach. Integrate message generation and retrieval with your tools.

Introduction

The Upscale API lets you integrate personalised LinkedIn message generation with your systems. Send prospects, receive generated messages, and get notified when processing is complete.

Base URL

https://app.upscaleoutreach.com/api/v2

Authentication

Send your API key in the request header and use JSON for the request body:

Api-Key: YOUR_API_KEY
Content-Type: application/json

You can find your API keys in your account settings.

Errors

The API returns standard HTTP status codes with JSON response bodies. Below are the main scenarios and example responses.

Status CodeScenarioResponse Body
401 UnauthorizedInvalid API key{"error": "Unauthorized: Invalid API key"}
401 UnauthorizedRevoked API key{"error": "Unauthorized: API key has been revoked"}
402 Payment RequiredInsufficient credits{"error": "Not enough credits remaining to complete this request. Please upgrade your plan or purchase a bundle."}
422 Unprocessable EntitySingle validation error{"error": "message_sequence must be an array"}
422 Unprocessable EntityMultiple validation errors{"error": "automation_tool_customer_id is required but was missing or blank proposition_company_url must be a valid HTTP or HTTPS URL lead_data[0].first_name is required but was missing or blank lead_data[1].lead_company is required but was missing or blank"}
422 Unprocessable EntityInvalid URL format{"error": "proposition_company_url must be a valid URL"}
422 Unprocessable EntityEmpty lead data{"error": "lead_data must contain at least one lead"}

Formatted JSON examples

Invalid API key (401):

{
  "error": "Unauthorized: Invalid API key"
}

Revoked API key (401):

{
  "error": "Unauthorized: API key has been revoked"
}

Insufficient credits (402):

{
  "error": "Not enough credits remaining to complete this request. Please upgrade your plan or purchase a bundle."
}

Validation error - single (422):

{
  "error": "message_sequence must be an array"
}

Validation error - multiple (422):

{
  "error": "automation_tool_customer_id is required but was missing or blank proposition_company_url must be a valid HTTP or HTTPS URL lead_data[0].first_name is required but was missing or blank lead_data[1].lead_company is required but was missing or blank"
}

Request Message Generation API

Submit a list of leads and your proposition details to request personalised LinkedIn messages. Provide a completion notification URL to receive a webhook when generation is finished.

Endpoint

MethodPath
POST/request_message_generation

Request

Request parameters

ParameterTypeRequiredDescription
All fields are mandatory except lead_specified_url and lead_company_website_url on each lead.
completion_notification_urlstring (URL)YesWebhook URL to receive notification when message generation is complete
automation_tool_customer_idstringYesYour internal customer/account identifier
automation_tool_campaign_idstringYesYour internal campaign identifier
proposition_company_namestringYesThe name of the campaign proposition company (for personalization)
proposition_company_urlstring (URL)YesThe website of that company (must be valid HTTP/HTTPS)
message_sequencearray of stringsYesArray of message types to generate. Allowed values: connection_request, first_follow_up, share_material, hiring_activity. Values coming soon: industry_insight, proposition_summary, breakup, linkedin_post, re-engagement, youtube_content, trustpilot_reviews
tone_preferencestringNoOptional. One of: formal, normal, or casual only. Default is normal if omitted.
lead_dataarrayYesArray of lead objects (minimum 1 required)

Lead data object parameters

ParameterTypeRequiredDescription
automation_tool_lead_idstringYesYour internal lead/prospect identifier
lead_linkedinstring (URL)YesLinkedIn profile URL of the prospect
lead_companystringYesCompany name where the prospect works
first_namestringYesProspect's first name
last_namestringYesProspect's last name
lead_company_website_urlstring (URL)NoCompany website URL (optional)
lead_specified_urlstring (URL)NoSpecific URL for research (optional). If provided, this URL is used for research instead of lead_company_website_url. When both are given, lead_specified_url takes precedence over any website URL.

Notes

  • The message_sequence array determines which message types will be generated for each prospect.
  • The completion_notification_url is required so you receive webhook notifications when generation completes.
  • All lead_data entries must include the required fields listed above.
  • The API returns a secure_request_id that you use with the Retrieve Messages API to fetch the generated messages.

Example request (JSON body)

{
  "completion_notification_url": "https://your-webhook-endpoint.com/webhook",
  "automation_tool_customer_id": "customer_12345",
  "automation_tool_campaign_id": "campaign_67890",
  "proposition_company_name": "Acme Corporation",
  "proposition_company_url": "https://www.acmecorp.com",
  "message_sequence": ["connection_request", "first_follow_up"],
  "tone_preference": "formal",
  "lead_data": [
    {
      "automation_tool_lead_id": "lead_001",
      "lead_linkedin": "https://linkedin.com/in/john-doe",
      "lead_company": "Tech Solutions Inc",
      "first_name": "John",
      "last_name": "Doe",
      "lead_company_website_url": "https://www.techsolutions.com",
      "lead_specified_url": null
    },
    {
      "automation_tool_lead_id": "lead_002",
      "lead_linkedin": "https://linkedin.com/in/jane-smith",
      "lead_company": "Digital Innovations LLC",
      "first_name": "Jane",
      "last_name": "Smith",
      "lead_company_website_url": "https://www.digitalinnovations.com",
      "lead_specified_url": null
    }
  ]
}

Complete cURL example

curl --location 'https://app.upscaleoutreach.com/api/v2/request_message_generation' \
--header 'Api-Key: your_api_key_here' \
--header 'Content-Type: application/json' \
--data '{
  "completion_notification_url": "https://your-webhook-endpoint.com/webhook",
  "automation_tool_customer_id": "customer_12345",
  "automation_tool_campaign_id": "campaign_67890",
  "proposition_company_name": "Acme Corporation",
  "proposition_company_url": "https://www.acmecorp.com",
  "message_sequence": ["connection_request", "first_follow_up"],
  "tone_preference": "casual",
  "lead_data": [
    {
      "automation_tool_lead_id": "lead_001",
      "lead_linkedin": "https://linkedin.com/in/john-doe",
      "lead_company": "Tech Solutions Inc",
      "first_name": "John",
      "last_name": "Doe",
      "lead_company_website_url": "https://www.techsolutions.com",
      "lead_specified_url": null
    },
    {
      "automation_tool_lead_id": "lead_002",
      "lead_linkedin": "https://linkedin.com/in/jane-smith",
      "lead_company": "Digital Innovations LLC",
      "first_name": "Jane",
      "last_name": "Smith",
      "lead_company_website_url": "https://www.digitalinnovations.com",
      "lead_specified_url": null
    }
  ]
}'

Example with fetch (JavaScript)

fetch('https://app.upscaleoutreach.com/api/v2/request_message_generation', {
  method: 'POST',
  headers: {
    'Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    completion_notification_url: 'https://your-webhook-endpoint.com/webhook',
    automation_tool_customer_id: 'customer_12345',
    automation_tool_campaign_id: 'campaign_67890',
    proposition_company_name: 'Acme Corporation',
    proposition_company_url: 'https://www.acmecorp.com',
    message_sequence: ['connection_request', 'first_follow_up'],
    tone_preference: 'formal',
    lead_data: [ /* ... */ ]
  })
})

Response

On success (200), the response includes message and secure_request_id. Use secure_request_id to retrieve the generated messages (see Retrieve Messages API) and to identify the request in completion webhook payloads.

{
  "message": "Success",
  "secure_request_id": "3d68ae3b-5957-454d-be1c-8731a4f877f6"
}

Retrieve Messages API

Fetch the generated messages for a request. Send the secure_request_id returned from the Request Message Generation API to retrieve all messages (and metadata) for that request.

Endpoint

MethodPath
GET/retrieve_messages

Headers: Api-Key: your_api_key_here, Content-Type: application/json

Request

Request parameters

ParameterTypeRequiredDescription
request_message_generation_secure_request_idstring (UUID)YesThe secure_request_id returned from the Request Message Generation API (/request_message_generation)

Notes

  • The request_message_generation_secure_request_id is the secure_request_id value returned in the success response from the Request Message Generation API.
  • The Api-Key header must contain a valid, non-revoked API key.
  • The response returns generated messages for all prospects associated with that original message generation request.

Example request (JSON body)

{
  "request_message_generation_secure_request_id": "550e8400-e29b-41d4-a716-446655440000"
}

Complete cURL example

curl --location --request GET 'https://app.upscaleoutreach.com/api/v2/retrieve_messages' \
--header 'Api-Key: your_api_key_here' \
--header 'Content-Type: application/json' \
--data '{
  "request_message_generation_secure_request_id": "550e8400-e29b-41d4-a716-446655440000"
}'

Response

On success (200), the response includes metadata, account, and campaign. The campaign.leads_data array contains one object per lead, with message fields (outreach_message, first_follow_up_message, share_material_message, hiring_activity_message) matching the message_sequence. When a message could not be generated for a prospect, that lead's fields may be null and metadata.failed_messages_count and metadata.failed_messages_reason are populated.

200 OK - Success (all messages generated)

Scenario: All requested messages were successfully generated.

{
  "metadata": {
    "request_message_generation_api_request_secure_request_id": "550e8400-e29b-41d4-a716-446655440000",
    "retrieve_messages_api_request_secure_request_id": "660e8400-e29b-41d4-a716-446655440001",
    "requested_messages_count": 5,
    "generated_messages_count": 5,
    "failed_messages_count": null,
    "failed_messages_reason": null
  },
  "account": {
    "automation_tool_customer_id": "customer_12345"
  },
  "campaign": {
    "automation_tool_campaign_id": "campaign_67890",
    "message_sequence": ["connection_request", "first_follow_up"],
    "leads_data": [
      {
        "external_prospect_id": "lead_001",
        "linkedin": "https://linkedin.com/in/john-doe",
        "outreach_message": "Hi John, I noticed your work at Acme Corp and thought you might be interested in learning about our solution that helps companies like yours streamline their operations.",
        "first_follow_up_message": "Hi John, following up on my previous message. I'd love to share how we've helped similar companies achieve significant cost savings.",
        "share_material_message": null,
        "hiring_activity_message": null
      },
      {
        "external_prospect_id": "lead_002",
        "linkedin": "https://linkedin.com/in/jane-smith",
        "outreach_message": "Hi Jane, I saw your recent post about digital transformation and thought our platform might be relevant to your work.",
        "first_follow_up_message": "Hi Jane, I wanted to follow up and see if you'd be open to a brief conversation about how we can help.",
        "share_material_message": null,
        "hiring_activity_message": null
      },
      {
        "external_prospect_id": "lead_003",
        "linkedin": "https://linkedin.com/in/bob-johnson",
        "outreach_message": "Hi Bob, I noticed your company's recent expansion and thought you might benefit from our services.",
        "first_follow_up_message": "Hi Bob, following up to see if you'd like to learn more about how we can support your growth.",
        "share_material_message": null,
        "hiring_activity_message": null
      }
    ]
  }
}

200 OK - Success (some messages failed)

Scenario: Some requested messages failed to generate (e.g. insufficient web presence for research). No credits are deducted for failed prospects.

{
  "metadata": {
    "request_message_generation_api_request_secure_request_id": "550e8400-e29b-41d4-a716-446655440000",
    "retrieve_messages_api_request_secure_request_id": "660e8400-e29b-41d4-a716-446655440001",
    "requested_messages_count": 10,
    "generated_messages_count": 7,
    "failed_messages_count": 3,
    "failed_messages_reason": "Some prospects do not have enough available web presence for research (including having limited information on LinkedIn, a website that blocks scrapers, and/or a website that is not indexed by search engines). For these prospects, personalisation is not possible. No credits were deducted for these prospects."
  },
  "account": {
    "automation_tool_customer_id": "customer_12345"
  },
  "campaign": {
    "automation_tool_campaign_id": "campaign_67890",
    "message_sequence": ["connection_request", "first_follow_up", "share_material_message"],
    "leads_data": [
      {
        "external_prospect_id": "lead_001",
        "linkedin": "https://linkedin.com/in/john-doe",
        "outreach_message": "Hi John, I noticed your work at Acme Corp and thought you might be interested in learning about our solution.",
        "first_follow_up_message": "Hi John, following up on my previous message about how we can help streamline your operations.",
        "share_material_message": "Hi John, I thought you might find this resource helpful for your current projects.",
        "hiring_activity_message": null
      },
      {
        "external_prospect_id": "lead_002",
        "linkedin": "https://linkedin.com/in/jane-smith",
        "outreach_message": "Hi Jane, I saw your recent post about digital transformation and thought our platform might be relevant.",
        "first_follow_up_message": "Hi Jane, I wanted to follow up and see if you'd be open to a brief conversation.",
        "share_material_message": "Hi Jane, I thought you might find this case study helpful - it covers similar challenges to what you're facing.",
        "hiring_activity_message": null
      },
      {
        "external_prospect_id": "lead_003",
        "linkedin": null,
        "outreach_message": null,
        "first_follow_up_message": null,
        "share_material_message": null,
        "hiring_activity_message": null
      },
      {
        "external_prospect_id": "lead_004",
        "linkedin": null,
        "outreach_message": null,
        "first_follow_up_message": null,
        "share_material_message": null,
        "hiring_activity_message": null
      },
      {
        "external_prospect_id": "lead_005",
        "linkedin": null,
        "outreach_message": null,
        "first_follow_up_message": null,
        "share_material_message": null,
        "hiring_activity_message": null
      }
    ]
  }
}

Error response examples

Validation error (e.g. 422):

{
  "error": "request_message_generation_secure_request_id is required but was missing or blank",
  "status": "error"
}

Unauthorized (401):

{
  "error": "Unauthorized: API key has been revoked",
  "status": "error"
}

Get Sequences API

Retrieve available message sequences (and their types) that can be used in the Request Message Generation API. Show these sequences to your users to help them choose the best sequence for their campaign.

Each sequence is associated with a role, industry, geography, and objective - any of which can be used by the user to choose which sequence to use.

These sequences are generated by Upscale based on best practices for LinkedIn outreach - and what we are seeing work best. You can also customise a sequence to your own needs; the Request Message Generation API only needs the list of all message types you want to use in the campaign.

Endpoint

MethodPath
GET/get_sequences (this is a placeholder - details to be confirmed)

Headers: Api-Key: your_api_key_here, Content-Type: application/json

Request

Request parameters

ParameterTypeRequiredDescription
(placeholder)--Request parameters to be documented.

Notes

  • Placeholder: request notes and example to be added.

Example request

curl -X GET "https://app.upscaleoutreach.com/api/v2/get_sequences" \
  -H "Api-Key: your_api_key_here" \
  -H "Content-Type: application/json"

Response

On success (200), the response returns the list of available sequences. Placeholder structure below - to be updated with actual fields.

200 OK - Success

{
  "sequences": [
    {
      "id": "placeholder",
      "name": "Placeholder sequence",
      "message_types": ["connection_request", "first_follow_up"],
      "role": "sales",
      "industry": "technology",
      "geography": "north_america",
      "objective": "demonstrate expertise"
    }
  ]
}

Error response examples

Unauthorized (401):

{
  "error": "Unauthorized: API key invalid or revoked",
  "status": "error"
}

Account API

Check your account status at any time. The endpoint responds with quota levels and current usage (e.g. message credits). Usage typically resets on a recurring basis. This is a placeholder - details to be added.

Endpoint

MethodPath
GET/account (this is a placeholder - details to be confirmed)

Headers: Api-Key: your_api_key_here, Content-Type: application/json

Request

Request parameters

ParameterTypeRequiredDescription
(none)--No request body; authentication via Api-Key header.

Notes

  • Placeholder: request notes and example to be added.

Example request

curl -X GET "https://app.upscaleoutreach.com/api/v2/account" \
  -H "Api-Key: your_api_key_here" \
  -H "Content-Type: application/json"

Response

On success (200), the response returns account details including quota and usage. Placeholder structure below - to be updated with actual fields.

200 OK - Success

{
  "created_at": "2024-01-15T10:00:00Z",
  "plan_name": "Placeholder plan",
  "monthly_credits": 0,
  "monthly_allowance": 1000
}

Error response examples

Unauthorized (401):

{
  "error": "Unauthorized: API key invalid or revoked",
  "status": "error"
}

Webhooks

When you request message generation, you can provide a URL to receive a notification as soon as the batch is finished. No separate webhook registration is required.

Required: Webhook secret

You must have generated your webhook secret in your account (next to your API key) in order to receive the completion notification. Without it, the webhook will not be sent.

Completion notification

Prerequisite: Pass completion_notification_url in your Request Message Generation API call. That URL receives a single POST request when the batch is done.

As soon as the final message is generated from the requested batch, the notification is sent to the provided URL. Use the payload to reconcile requested_messages_count vs generated_messages_count and to look up the batch via secure_request_id (e.g. with the Retrieve Messages API).

Example webhook payload

The request body is JSON with the following fields:

FieldTypeDescription
secure_request_idstringUnique identifier for the message generation request; use with Retrieve Messages API
statusstringStatus of the batch (e.g. complete)
completed_atstring (ISO 8601)Timestamp when generation completed (UTC)
requested_messages_countintegerTotal number of messages requested in the batch
generated_messages_countintegerNumber of messages successfully generated
{
  "secure_request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "complete",
  "completed_at": "2024-02-08T11:30:45Z",
  "requested_messages_count": 12,
  "generated_messages_count": 12
}

Archived documentation

The following APIs and webhook are archived. They remain available for reference and existing integrations.

View archive index →