universal-mcp-applications 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- universal_mcp/applications/ahrefs/README.md +51 -0
- universal_mcp/applications/ahrefs/__init__.py +1 -0
- universal_mcp/applications/ahrefs/app.py +2291 -0
- universal_mcp/applications/airtable/README.md +22 -0
- universal_mcp/applications/airtable/__init__.py +1 -0
- universal_mcp/applications/airtable/app.py +479 -0
- universal_mcp/applications/apollo/README.md +44 -0
- universal_mcp/applications/apollo/__init__.py +1 -0
- universal_mcp/applications/apollo/app.py +1847 -0
- universal_mcp/applications/asana/README.md +199 -0
- universal_mcp/applications/asana/__init__.py +1 -0
- universal_mcp/applications/asana/app.py +9509 -0
- universal_mcp/applications/aws-s3/README.md +0 -0
- universal_mcp/applications/aws-s3/__init__.py +1 -0
- universal_mcp/applications/aws-s3/app.py +552 -0
- universal_mcp/applications/bill/README.md +0 -0
- universal_mcp/applications/bill/__init__.py +1 -0
- universal_mcp/applications/bill/app.py +8705 -0
- universal_mcp/applications/box/README.md +307 -0
- universal_mcp/applications/box/__init__.py +1 -0
- universal_mcp/applications/box/app.py +15987 -0
- universal_mcp/applications/braze/README.md +106 -0
- universal_mcp/applications/braze/__init__.py +1 -0
- universal_mcp/applications/braze/app.py +4754 -0
- universal_mcp/applications/cal-com-v2/README.md +150 -0
- universal_mcp/applications/cal-com-v2/__init__.py +1 -0
- universal_mcp/applications/cal-com-v2/app.py +5541 -0
- universal_mcp/applications/calendly/README.md +53 -0
- universal_mcp/applications/calendly/__init__.py +1 -0
- universal_mcp/applications/calendly/app.py +1436 -0
- universal_mcp/applications/canva/README.md +43 -0
- universal_mcp/applications/canva/__init__.py +1 -0
- universal_mcp/applications/canva/app.py +941 -0
- universal_mcp/applications/clickup/README.md +135 -0
- universal_mcp/applications/clickup/__init__.py +1 -0
- universal_mcp/applications/clickup/app.py +5009 -0
- universal_mcp/applications/coda/README.md +108 -0
- universal_mcp/applications/coda/__init__.py +1 -0
- universal_mcp/applications/coda/app.py +3671 -0
- universal_mcp/applications/confluence/README.md +198 -0
- universal_mcp/applications/confluence/__init__.py +1 -0
- universal_mcp/applications/confluence/app.py +6273 -0
- universal_mcp/applications/contentful/README.md +17 -0
- universal_mcp/applications/contentful/__init__.py +1 -0
- universal_mcp/applications/contentful/app.py +364 -0
- universal_mcp/applications/crustdata/README.md +25 -0
- universal_mcp/applications/crustdata/__init__.py +1 -0
- universal_mcp/applications/crustdata/app.py +586 -0
- universal_mcp/applications/dialpad/README.md +202 -0
- universal_mcp/applications/dialpad/__init__.py +1 -0
- universal_mcp/applications/dialpad/app.py +5949 -0
- universal_mcp/applications/digitalocean/README.md +463 -0
- universal_mcp/applications/digitalocean/__init__.py +1 -0
- universal_mcp/applications/digitalocean/app.py +20835 -0
- universal_mcp/applications/domain-checker/README.md +13 -0
- universal_mcp/applications/domain-checker/__init__.py +1 -0
- universal_mcp/applications/domain-checker/app.py +265 -0
- universal_mcp/applications/e2b/README.md +12 -0
- universal_mcp/applications/e2b/__init__.py +1 -0
- universal_mcp/applications/e2b/app.py +187 -0
- universal_mcp/applications/elevenlabs/README.md +88 -0
- universal_mcp/applications/elevenlabs/__init__.py +1 -0
- universal_mcp/applications/elevenlabs/app.py +3235 -0
- universal_mcp/applications/exa/README.md +15 -0
- universal_mcp/applications/exa/__init__.py +1 -0
- universal_mcp/applications/exa/app.py +221 -0
- universal_mcp/applications/falai/README.md +17 -0
- universal_mcp/applications/falai/__init__.py +1 -0
- universal_mcp/applications/falai/app.py +331 -0
- universal_mcp/applications/figma/README.md +49 -0
- universal_mcp/applications/figma/__init__.py +1 -0
- universal_mcp/applications/figma/app.py +1090 -0
- universal_mcp/applications/firecrawl/README.md +20 -0
- universal_mcp/applications/firecrawl/__init__.py +1 -0
- universal_mcp/applications/firecrawl/app.py +514 -0
- universal_mcp/applications/fireflies/README.md +25 -0
- universal_mcp/applications/fireflies/__init__.py +1 -0
- universal_mcp/applications/fireflies/app.py +506 -0
- universal_mcp/applications/fpl/README.md +23 -0
- universal_mcp/applications/fpl/__init__.py +1 -0
- universal_mcp/applications/fpl/app.py +1327 -0
- universal_mcp/applications/fpl/utils/api.py +142 -0
- universal_mcp/applications/fpl/utils/fixtures.py +629 -0
- universal_mcp/applications/fpl/utils/helper.py +982 -0
- universal_mcp/applications/fpl/utils/league_utils.py +546 -0
- universal_mcp/applications/fpl/utils/position_utils.py +68 -0
- universal_mcp/applications/ghost-content/README.md +25 -0
- universal_mcp/applications/ghost-content/__init__.py +1 -0
- universal_mcp/applications/ghost-content/app.py +654 -0
- universal_mcp/applications/github/README.md +1049 -0
- universal_mcp/applications/github/__init__.py +1 -0
- universal_mcp/applications/github/app.py +50600 -0
- universal_mcp/applications/gong/README.md +63 -0
- universal_mcp/applications/gong/__init__.py +1 -0
- universal_mcp/applications/gong/app.py +2297 -0
- universal_mcp/applications/google-ads/README.md +0 -0
- universal_mcp/applications/google-ads/__init__.py +1 -0
- universal_mcp/applications/google-ads/app.py +23 -0
- universal_mcp/applications/google-calendar/README.md +21 -0
- universal_mcp/applications/google-calendar/__init__.py +1 -0
- universal_mcp/applications/google-calendar/app.py +574 -0
- universal_mcp/applications/google-docs/README.md +25 -0
- universal_mcp/applications/google-docs/__init__.py +1 -0
- universal_mcp/applications/google-docs/app.py +760 -0
- universal_mcp/applications/google-drive/README.md +68 -0
- universal_mcp/applications/google-drive/__init__.py +1 -0
- universal_mcp/applications/google-drive/app.py +4936 -0
- universal_mcp/applications/google-gemini/README.md +25 -0
- universal_mcp/applications/google-gemini/__init__.py +1 -0
- universal_mcp/applications/google-gemini/app.py +663 -0
- universal_mcp/applications/google-mail/README.md +31 -0
- universal_mcp/applications/google-mail/__init__.py +1 -0
- universal_mcp/applications/google-mail/app.py +1354 -0
- universal_mcp/applications/google-searchconsole/README.md +21 -0
- universal_mcp/applications/google-searchconsole/__init__.py +1 -0
- universal_mcp/applications/google-searchconsole/app.py +320 -0
- universal_mcp/applications/google-sheet/README.md +36 -0
- universal_mcp/applications/google-sheet/__init__.py +1 -0
- universal_mcp/applications/google-sheet/app.py +1941 -0
- universal_mcp/applications/hashnode/README.md +20 -0
- universal_mcp/applications/hashnode/__init__.py +1 -0
- universal_mcp/applications/hashnode/app.py +455 -0
- universal_mcp/applications/heygen/README.md +44 -0
- universal_mcp/applications/heygen/__init__.py +1 -0
- universal_mcp/applications/heygen/app.py +961 -0
- universal_mcp/applications/http-tools/README.md +16 -0
- universal_mcp/applications/http-tools/__init__.py +1 -0
- universal_mcp/applications/http-tools/app.py +153 -0
- universal_mcp/applications/hubspot/README.md +239 -0
- universal_mcp/applications/hubspot/__init__.py +1 -0
- universal_mcp/applications/hubspot/app.py +416 -0
- universal_mcp/applications/jira/README.md +600 -0
- universal_mcp/applications/jira/__init__.py +1 -0
- universal_mcp/applications/jira/app.py +28804 -0
- universal_mcp/applications/klaviyo/README.md +313 -0
- universal_mcp/applications/klaviyo/__init__.py +1 -0
- universal_mcp/applications/klaviyo/app.py +11236 -0
- universal_mcp/applications/linkedin/README.md +15 -0
- universal_mcp/applications/linkedin/__init__.py +1 -0
- universal_mcp/applications/linkedin/app.py +243 -0
- universal_mcp/applications/mailchimp/README.md +281 -0
- universal_mcp/applications/mailchimp/__init__.py +1 -0
- universal_mcp/applications/mailchimp/app.py +10937 -0
- universal_mcp/applications/markitdown/README.md +12 -0
- universal_mcp/applications/markitdown/__init__.py +1 -0
- universal_mcp/applications/markitdown/app.py +63 -0
- universal_mcp/applications/miro/README.md +151 -0
- universal_mcp/applications/miro/__init__.py +1 -0
- universal_mcp/applications/miro/app.py +5429 -0
- universal_mcp/applications/ms-teams/README.md +42 -0
- universal_mcp/applications/ms-teams/__init__.py +1 -0
- universal_mcp/applications/ms-teams/app.py +1823 -0
- universal_mcp/applications/neon/README.md +74 -0
- universal_mcp/applications/neon/__init__.py +1 -0
- universal_mcp/applications/neon/app.py +2018 -0
- universal_mcp/applications/notion/README.md +30 -0
- universal_mcp/applications/notion/__init__.py +1 -0
- universal_mcp/applications/notion/app.py +527 -0
- universal_mcp/applications/openai/README.md +22 -0
- universal_mcp/applications/openai/__init__.py +1 -0
- universal_mcp/applications/openai/app.py +759 -0
- universal_mcp/applications/outlook/README.md +20 -0
- universal_mcp/applications/outlook/__init__.py +1 -0
- universal_mcp/applications/outlook/app.py +444 -0
- universal_mcp/applications/perplexity/README.md +12 -0
- universal_mcp/applications/perplexity/__init__.py +1 -0
- universal_mcp/applications/perplexity/app.py +65 -0
- universal_mcp/applications/pipedrive/README.md +284 -0
- universal_mcp/applications/pipedrive/__init__.py +1 -0
- universal_mcp/applications/pipedrive/app.py +12924 -0
- universal_mcp/applications/posthog/README.md +132 -0
- universal_mcp/applications/posthog/__init__.py +1 -0
- universal_mcp/applications/posthog/app.py +7125 -0
- universal_mcp/applications/reddit/README.md +135 -0
- universal_mcp/applications/reddit/__init__.py +1 -0
- universal_mcp/applications/reddit/app.py +4652 -0
- universal_mcp/applications/replicate/README.md +18 -0
- universal_mcp/applications/replicate/__init__.py +1 -0
- universal_mcp/applications/replicate/app.py +495 -0
- universal_mcp/applications/resend/README.md +40 -0
- universal_mcp/applications/resend/__init__.py +1 -0
- universal_mcp/applications/resend/app.py +881 -0
- universal_mcp/applications/retell/README.md +21 -0
- universal_mcp/applications/retell/__init__.py +1 -0
- universal_mcp/applications/retell/app.py +333 -0
- universal_mcp/applications/rocketlane/README.md +70 -0
- universal_mcp/applications/rocketlane/__init__.py +1 -0
- universal_mcp/applications/rocketlane/app.py +4346 -0
- universal_mcp/applications/semanticscholar/README.md +25 -0
- universal_mcp/applications/semanticscholar/__init__.py +1 -0
- universal_mcp/applications/semanticscholar/app.py +482 -0
- universal_mcp/applications/semrush/README.md +44 -0
- universal_mcp/applications/semrush/__init__.py +1 -0
- universal_mcp/applications/semrush/app.py +2081 -0
- universal_mcp/applications/sendgrid/README.md +362 -0
- universal_mcp/applications/sendgrid/__init__.py +1 -0
- universal_mcp/applications/sendgrid/app.py +9752 -0
- universal_mcp/applications/sentry/README.md +186 -0
- universal_mcp/applications/sentry/__init__.py +1 -0
- universal_mcp/applications/sentry/app.py +7471 -0
- universal_mcp/applications/serpapi/README.md +14 -0
- universal_mcp/applications/serpapi/__init__.py +1 -0
- universal_mcp/applications/serpapi/app.py +293 -0
- universal_mcp/applications/sharepoint/README.md +0 -0
- universal_mcp/applications/sharepoint/__init__.py +1 -0
- universal_mcp/applications/sharepoint/app.py +215 -0
- universal_mcp/applications/shopify/README.md +321 -0
- universal_mcp/applications/shopify/__init__.py +1 -0
- universal_mcp/applications/shopify/app.py +15392 -0
- universal_mcp/applications/shortcut/README.md +128 -0
- universal_mcp/applications/shortcut/__init__.py +1 -0
- universal_mcp/applications/shortcut/app.py +4478 -0
- universal_mcp/applications/slack/README.md +0 -0
- universal_mcp/applications/slack/__init__.py +1 -0
- universal_mcp/applications/slack/app.py +570 -0
- universal_mcp/applications/spotify/README.md +91 -0
- universal_mcp/applications/spotify/__init__.py +1 -0
- universal_mcp/applications/spotify/app.py +2526 -0
- universal_mcp/applications/supabase/README.md +87 -0
- universal_mcp/applications/supabase/__init__.py +1 -0
- universal_mcp/applications/supabase/app.py +2970 -0
- universal_mcp/applications/tavily/README.md +12 -0
- universal_mcp/applications/tavily/__init__.py +1 -0
- universal_mcp/applications/tavily/app.py +51 -0
- universal_mcp/applications/trello/README.md +266 -0
- universal_mcp/applications/trello/__init__.py +1 -0
- universal_mcp/applications/trello/app.py +10875 -0
- universal_mcp/applications/twillo/README.md +0 -0
- universal_mcp/applications/twillo/__init__.py +1 -0
- universal_mcp/applications/twillo/app.py +269 -0
- universal_mcp/applications/twitter/README.md +100 -0
- universal_mcp/applications/twitter/__init__.py +1 -0
- universal_mcp/applications/twitter/api_segments/__init__.py +0 -0
- universal_mcp/applications/twitter/api_segments/api_segment_base.py +51 -0
- universal_mcp/applications/twitter/api_segments/compliance_api.py +122 -0
- universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +255 -0
- universal_mcp/applications/twitter/api_segments/dm_events_api.py +140 -0
- universal_mcp/applications/twitter/api_segments/likes_api.py +159 -0
- universal_mcp/applications/twitter/api_segments/lists_api.py +395 -0
- universal_mcp/applications/twitter/api_segments/openapi_json_api.py +34 -0
- universal_mcp/applications/twitter/api_segments/spaces_api.py +309 -0
- universal_mcp/applications/twitter/api_segments/trends_api.py +40 -0
- universal_mcp/applications/twitter/api_segments/tweets_api.py +1403 -0
- universal_mcp/applications/twitter/api_segments/usage_api.py +40 -0
- universal_mcp/applications/twitter/api_segments/users_api.py +1498 -0
- universal_mcp/applications/twitter/app.py +46 -0
- universal_mcp/applications/unipile/README.md +28 -0
- universal_mcp/applications/unipile/__init__.py +1 -0
- universal_mcp/applications/unipile/app.py +829 -0
- universal_mcp/applications/whatsapp/README.md +23 -0
- universal_mcp/applications/whatsapp/__init__.py +1 -0
- universal_mcp/applications/whatsapp/app.py +595 -0
- universal_mcp/applications/whatsapp-business/README.md +34 -0
- universal_mcp/applications/whatsapp-business/__init__.py +1 -0
- universal_mcp/applications/whatsapp-business/app.py +1065 -0
- universal_mcp/applications/wrike/README.md +46 -0
- universal_mcp/applications/wrike/__init__.py +1 -0
- universal_mcp/applications/wrike/app.py +1583 -0
- universal_mcp/applications/youtube/README.md +57 -0
- universal_mcp/applications/youtube/__init__.py +1 -0
- universal_mcp/applications/youtube/app.py +1696 -0
- universal_mcp/applications/zenquotes/README.md +12 -0
- universal_mcp/applications/zenquotes/__init__.py +1 -0
- universal_mcp/applications/zenquotes/app.py +31 -0
- universal_mcp_applications-0.1.1.dist-info/METADATA +172 -0
- universal_mcp_applications-0.1.1.dist-info/RECORD +268 -0
- universal_mcp_applications-0.1.1.dist-info/WHEEL +4 -0
- universal_mcp_applications-0.1.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,1847 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from loguru import logger
|
|
4
|
+
from universal_mcp.applications.application import APIApplication
|
|
5
|
+
from universal_mcp.integrations import Integration
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ApolloApp(APIApplication):
|
|
9
|
+
def __init__(self, integration: Integration = None, **kwargs) -> None:
|
|
10
|
+
super().__init__(name="apollo", integration=integration, **kwargs)
|
|
11
|
+
self.base_url = "https://api.apollo.io/api/v1"
|
|
12
|
+
|
|
13
|
+
def _get_headers(self) -> dict[str, str]:
|
|
14
|
+
"""
|
|
15
|
+
Get the headers for Apollo API requests.
|
|
16
|
+
Overrides the base class method to use X-Api-Key.
|
|
17
|
+
"""
|
|
18
|
+
if not self.integration:
|
|
19
|
+
logger.warning(
|
|
20
|
+
"ApolloApp: No integration configured, returning empty headers."
|
|
21
|
+
)
|
|
22
|
+
return {}
|
|
23
|
+
|
|
24
|
+
# ApiKeyIntegration's get_credentials() returns a dict like:
|
|
25
|
+
# {'api_key': 'your_actual_key_value'}
|
|
26
|
+
credentials = self.integration.get_credentials()
|
|
27
|
+
|
|
28
|
+
# The key in the credentials dict from ApiKeyIntegration is 'api_key'
|
|
29
|
+
api_key = (
|
|
30
|
+
credentials.get("api_key")
|
|
31
|
+
or credentials.get("API_KEY")
|
|
32
|
+
or credentials.get("apiKey")
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
if not api_key:
|
|
36
|
+
logger.error(
|
|
37
|
+
"ApolloApp: API key not found in integration credentials for Apollo."
|
|
38
|
+
)
|
|
39
|
+
# You might want to raise an error here if an API key is absolutely required
|
|
40
|
+
# For example: raise ValueError("API key is missing for Apollo integration.")
|
|
41
|
+
return { # Or return minimal headers if some calls might not need auth (unlikely for Apollo)
|
|
42
|
+
"Content-Type": "application/json",
|
|
43
|
+
"Cache-Control": "no-cache",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
logger.debug("ApolloApp: Using X-Api-Key for authentication.")
|
|
47
|
+
return {
|
|
48
|
+
"X-Api-Key": api_key,
|
|
49
|
+
"Content-Type": "application/json",
|
|
50
|
+
"Cache-Control": "no-cache", # Often good practice for APIs
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
def people_enrichment(
|
|
54
|
+
self,
|
|
55
|
+
first_name: str | None = None,
|
|
56
|
+
last_name: str | None = None,
|
|
57
|
+
name: str | None = None,
|
|
58
|
+
email: str | None = None,
|
|
59
|
+
hashed_email: str | None = None,
|
|
60
|
+
organization_name: str | None = None,
|
|
61
|
+
domain: str | None = None,
|
|
62
|
+
id: str | None = None,
|
|
63
|
+
linkedin_url: str | None = None,
|
|
64
|
+
reveal_personal_emails: bool | None = None,
|
|
65
|
+
reveal_phone_number: bool | None = None,
|
|
66
|
+
webhook_url: str | None = None,
|
|
67
|
+
) -> dict[str, Any]:
|
|
68
|
+
"""
|
|
69
|
+
Matches a person based on provided identifying information such as name, email, organization, or LinkedIn URL, with options to reveal personal emails and phone numbers.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
first_name (string): The first name of the person to match, typically used together with the last_name parameter to identify an individual; example: "Tim".
|
|
73
|
+
last_name (string): The last name of the person to match, usually combined with the `first_name` parameter to improve accuracy; for example, `zheng`.
|
|
74
|
+
name (string): Full name of the person, typically a first name and last name separated by a space, replacing `first_name` and `last_name`.
|
|
75
|
+
email (string): Email address of the person to match; must be valid (e.g., example@email.com).
|
|
76
|
+
hashed_email (string): The hashed_email query parameter accepts an email address hashed in MD5 or SHA-256 format, such as `8d935115b9ff4489f2d1f9249503cadf` (MD5) or `97817c0c49994eb500ad0a5e7e2d8aed51977b26424d508f66e4e8887746a152` (SHA-256).
|
|
77
|
+
organization_name (string): The name of the person's current or past employer, used to identify their organization during the matching process. Example: `apollo`.
|
|
78
|
+
domain (string): The domain parameter is the employer's website domain for the person being matched, reflecting either current or previous employment; enter only the domain name without prefixes like www or symbols such as @, for example, apollo.io or microsoft.com.
|
|
79
|
+
id (string): Unique ID for the person in Apollo's database, obtained via the People Search endpoint.
|
|
80
|
+
linkedin_url (string): The URL of the person's LinkedIn profile, typically starting with "https://www.linkedin.com/in/", used to uniquely identify and match the individual in the system.
|
|
81
|
+
reveal_personal_emails (boolean): Enrich person data with personal emails by setting to `true`. This may consume credits and is subject to GDPR restrictions.
|
|
82
|
+
reveal_phone_number (boolean): Set to `true` to enrich person's data with available phone numbers, consuming credits. Requires a `webhook_url` for asynchronous verification and delivery.
|
|
83
|
+
webhook_url (string): If `reveal_phone_number` is true, provide this required webhook URL where Apollo will send a JSON response containing the requested phone number; otherwise, omit this parameter.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
dict[str, Any]: 200
|
|
87
|
+
|
|
88
|
+
Raises:
|
|
89
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
90
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
91
|
+
|
|
92
|
+
Tags:
|
|
93
|
+
People, important
|
|
94
|
+
"""
|
|
95
|
+
request_body_data = None
|
|
96
|
+
url = f"{self.base_url}/people/match"
|
|
97
|
+
query_params = {
|
|
98
|
+
k: v
|
|
99
|
+
for k, v in [
|
|
100
|
+
("first_name", first_name),
|
|
101
|
+
("last_name", last_name),
|
|
102
|
+
("name", name),
|
|
103
|
+
("email", email),
|
|
104
|
+
("hashed_email", hashed_email),
|
|
105
|
+
("organization_name", organization_name),
|
|
106
|
+
("domain", domain),
|
|
107
|
+
("id", id),
|
|
108
|
+
("linkedin_url", linkedin_url),
|
|
109
|
+
("reveal_personal_emails", reveal_personal_emails),
|
|
110
|
+
("reveal_phone_number", reveal_phone_number),
|
|
111
|
+
("webhook_url", webhook_url),
|
|
112
|
+
]
|
|
113
|
+
if v is not None
|
|
114
|
+
}
|
|
115
|
+
response = self._post(
|
|
116
|
+
url,
|
|
117
|
+
data=request_body_data,
|
|
118
|
+
params=query_params,
|
|
119
|
+
content_type="application/json",
|
|
120
|
+
)
|
|
121
|
+
response.raise_for_status()
|
|
122
|
+
if (
|
|
123
|
+
response.status_code == 204
|
|
124
|
+
or not response.content
|
|
125
|
+
or not response.text.strip()
|
|
126
|
+
):
|
|
127
|
+
return None
|
|
128
|
+
try:
|
|
129
|
+
return response.json()
|
|
130
|
+
except ValueError:
|
|
131
|
+
return None
|
|
132
|
+
|
|
133
|
+
def bulk_people_enrichment(
|
|
134
|
+
self,
|
|
135
|
+
reveal_personal_emails: bool | None = None,
|
|
136
|
+
reveal_phone_number: bool | None = None,
|
|
137
|
+
webhook_url: str | None = None,
|
|
138
|
+
details: list[dict[str, Any]] | None = None,
|
|
139
|
+
) -> dict[str, Any]:
|
|
140
|
+
"""
|
|
141
|
+
Performs a bulk match operation on people data using a POST request to the "/people/bulk_match" endpoint, accepting query parameters to control the reveal of personal emails and phone numbers, and optionally specifying a webhook URL, with the request body containing JSON data.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
reveal_personal_emails (boolean): Set to true to enrich matched people with personal emails, consuming credits; defaults to false. Personal emails won’t be revealed for individuals in GDPR-compliant regions.
|
|
145
|
+
reveal_phone_number (boolean): Set to `true` to enrich matched people with available phone numbers, consuming credits. Requires a `webhook_url` for asynchronous verification and delivery of phone details.
|
|
146
|
+
webhook_url (string): Optional webhook URL for receiving a JSON response with phone numbers if `reveal_phone_number` is `true`.
|
|
147
|
+
details (array): Provide info for each person you want to enrich as an object within this array. Add up to 10 people.
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
dict[str, Any]: 200
|
|
151
|
+
|
|
152
|
+
Raises:
|
|
153
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
154
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
155
|
+
|
|
156
|
+
Tags:
|
|
157
|
+
People
|
|
158
|
+
"""
|
|
159
|
+
request_body_data = None
|
|
160
|
+
request_body_data = {
|
|
161
|
+
"details": details,
|
|
162
|
+
}
|
|
163
|
+
request_body_data = {
|
|
164
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
165
|
+
}
|
|
166
|
+
url = f"{self.base_url}/people/bulk_match"
|
|
167
|
+
query_params = {
|
|
168
|
+
k: v
|
|
169
|
+
for k, v in [
|
|
170
|
+
("reveal_personal_emails", reveal_personal_emails),
|
|
171
|
+
("reveal_phone_number", reveal_phone_number),
|
|
172
|
+
("webhook_url", webhook_url),
|
|
173
|
+
]
|
|
174
|
+
if v is not None
|
|
175
|
+
}
|
|
176
|
+
response = self._post(
|
|
177
|
+
url,
|
|
178
|
+
data=request_body_data,
|
|
179
|
+
params=query_params,
|
|
180
|
+
content_type="application/json",
|
|
181
|
+
)
|
|
182
|
+
response.raise_for_status()
|
|
183
|
+
if (
|
|
184
|
+
response.status_code == 204
|
|
185
|
+
or not response.content
|
|
186
|
+
or not response.text.strip()
|
|
187
|
+
):
|
|
188
|
+
return None
|
|
189
|
+
try:
|
|
190
|
+
return response.json()
|
|
191
|
+
except ValueError:
|
|
192
|
+
return None
|
|
193
|
+
|
|
194
|
+
def organization_enrichment(self, domain: str) -> dict[str, Any]:
|
|
195
|
+
"""
|
|
196
|
+
Retrieves enriched organization data for a company specified by its domain name.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
domain (string): The domain query parameter specifies the company’s website domain to enrich, excluding prefixes like "www." or symbols such as "@"; for example, use "apollo.io" or "microsoft.com".
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
dict[str, Any]: 200
|
|
203
|
+
|
|
204
|
+
Raises:
|
|
205
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
206
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
207
|
+
|
|
208
|
+
Tags:
|
|
209
|
+
Organizations
|
|
210
|
+
"""
|
|
211
|
+
url = f"{self.base_url}/organizations/enrich"
|
|
212
|
+
query_params = {k: v for k, v in [("domain", domain)] if v is not None}
|
|
213
|
+
response = self._get(url, params=query_params)
|
|
214
|
+
response.raise_for_status()
|
|
215
|
+
if (
|
|
216
|
+
response.status_code == 204
|
|
217
|
+
or not response.content
|
|
218
|
+
or not response.text.strip()
|
|
219
|
+
):
|
|
220
|
+
return None
|
|
221
|
+
try:
|
|
222
|
+
return response.json()
|
|
223
|
+
except ValueError:
|
|
224
|
+
return None
|
|
225
|
+
|
|
226
|
+
def bulk_organization_enrichment(self, domains_: list[str]) -> dict[str, Any]:
|
|
227
|
+
"""
|
|
228
|
+
Enriches multiple organizations in bulk by submitting an array of domain names and returns detailed company profiles in a single request.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
domains_ (array): List of company domains to enrich, without "www.", "@", or similar prefixes—just the base domain, e.g., apollo.io, microsoft.com.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
dict[str, Any]: 200
|
|
235
|
+
|
|
236
|
+
Raises:
|
|
237
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
238
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
239
|
+
|
|
240
|
+
Tags:
|
|
241
|
+
Organizations
|
|
242
|
+
"""
|
|
243
|
+
request_body_data = None
|
|
244
|
+
url = f"{self.base_url}/organizations/bulk_enrich"
|
|
245
|
+
query_params = {k: v for k, v in [("domains[]", domains_)] if v is not None}
|
|
246
|
+
response = self._post(
|
|
247
|
+
url,
|
|
248
|
+
data=request_body_data,
|
|
249
|
+
params=query_params,
|
|
250
|
+
content_type="application/json",
|
|
251
|
+
)
|
|
252
|
+
response.raise_for_status()
|
|
253
|
+
if (
|
|
254
|
+
response.status_code == 204
|
|
255
|
+
or not response.content
|
|
256
|
+
or not response.text.strip()
|
|
257
|
+
):
|
|
258
|
+
return None
|
|
259
|
+
try:
|
|
260
|
+
return response.json()
|
|
261
|
+
except ValueError:
|
|
262
|
+
return None
|
|
263
|
+
|
|
264
|
+
def people_search(
|
|
265
|
+
self,
|
|
266
|
+
person_titles_: list[str] | None = None,
|
|
267
|
+
include_similar_titles: bool | None = None,
|
|
268
|
+
person_locations_: list[str] | None = None,
|
|
269
|
+
person_seniorities_: list[str] | None = None,
|
|
270
|
+
organization_locations_: list[str] | None = None,
|
|
271
|
+
q_organization_domains_list_: list[str] | None = None,
|
|
272
|
+
contact_email_status_: list[str] | None = None,
|
|
273
|
+
organization_ids_: list[str] | None = None,
|
|
274
|
+
organization_num_employees_ranges_: list[str] | None = None,
|
|
275
|
+
q_keywords: str | None = None,
|
|
276
|
+
page: int | None = None,
|
|
277
|
+
per_page: int | None = None,
|
|
278
|
+
) -> dict[str, Any]:
|
|
279
|
+
"""
|
|
280
|
+
Searches for people matching specified criteria including titles, locations, seniorities, organization details, and keywords, returning paginated results.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
person_titles_ (array): Specify job titles to find matching people; only one listed title needs to match, and partial matches are included. Combine with person_seniorities[] for refined results.
|
|
284
|
+
include_similar_titles (boolean): This parameter controls whether the search includes people with job titles similar to those specified in `person_titles[]`; set to false to return only exact title matches. Example: 'true'.
|
|
285
|
+
person_locations_ (array): The locations where people reside, searchable by city, US state, or country; to filter by employer headquarters, use the `organization_locations` parameter instead.
|
|
286
|
+
person_seniorities_ (array): The 'person_seniorities[]' query parameter filters people by their current job seniority level within their employer, such as Director or Senior IC; matching any listed seniority expands results, which reflect only present titles and can be combined
|
|
287
|
+
organization_locations_ (array): The organization_locations[] parameter filters people by the headquarters location of their current employer’s company, searchable by city, state, or country; office locations do not affect results.
|
|
288
|
+
q_organization_domains_list_ (array): The domain names of a person’s current or past employers, without prefixes like `www.` or symbols like `@`; accepts up to 1,000 domains per request, e.g., `apollo.io`, `microsoft.com`.
|
|
289
|
+
contact_email_status_ (array): The contact_email_status[] parameter filters people by their email verification status; you can specify multiple values like verified, unverified, likely to engage, or unavailable to broaden your search.
|
|
290
|
+
organization_ids_ (array): The Apollo IDs of companies (employers) to include in your search results; each company has a unique ID found via the Organization Search endpoint (e.g., `5e66b6381e05b4008c8331b8`).
|
|
291
|
+
organization_num_employees_ranges_ (array): Filter people by the employee count of their company using ranges (e.g., `1,10`, `250,500`). Multiple ranges can be added to expand search results.
|
|
292
|
+
q_keywords (string): A string of keywords used to filter search results.
|
|
293
|
+
page (integer): The page number of Apollo data to retrieve, used with `per_page` to paginate results and optimize endpoint performance; for example, `4`.
|
|
294
|
+
per_page (integer): The number of results to return per page in the search response; limiting this improves performance. Use the `page` parameter to access additional pages of results.
|
|
295
|
+
|
|
296
|
+
Returns:
|
|
297
|
+
dict[str, Any]: 200
|
|
298
|
+
|
|
299
|
+
Raises:
|
|
300
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
301
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
302
|
+
|
|
303
|
+
Tags:
|
|
304
|
+
People
|
|
305
|
+
"""
|
|
306
|
+
request_body_data = None
|
|
307
|
+
url = f"{self.base_url}/mixed_people/search"
|
|
308
|
+
query_params = {
|
|
309
|
+
k: v
|
|
310
|
+
for k, v in [
|
|
311
|
+
("person_titles[]", person_titles_),
|
|
312
|
+
("include_similar_titles", include_similar_titles),
|
|
313
|
+
("person_locations[]", person_locations_),
|
|
314
|
+
("person_seniorities[]", person_seniorities_),
|
|
315
|
+
("organization_locations[]", organization_locations_),
|
|
316
|
+
("q_organization_domains_list[]", q_organization_domains_list_),
|
|
317
|
+
("contact_email_status[]", contact_email_status_),
|
|
318
|
+
("organization_ids[]", organization_ids_),
|
|
319
|
+
(
|
|
320
|
+
"organization_num_employees_ranges[]",
|
|
321
|
+
organization_num_employees_ranges_,
|
|
322
|
+
),
|
|
323
|
+
("q_keywords", q_keywords),
|
|
324
|
+
("page", page),
|
|
325
|
+
("per_page", per_page),
|
|
326
|
+
]
|
|
327
|
+
if v is not None
|
|
328
|
+
}
|
|
329
|
+
response = self._post(
|
|
330
|
+
url,
|
|
331
|
+
data=request_body_data,
|
|
332
|
+
params=query_params,
|
|
333
|
+
content_type="application/json",
|
|
334
|
+
)
|
|
335
|
+
response.raise_for_status()
|
|
336
|
+
if (
|
|
337
|
+
response.status_code == 204
|
|
338
|
+
or not response.content
|
|
339
|
+
or not response.text.strip()
|
|
340
|
+
):
|
|
341
|
+
return None
|
|
342
|
+
try:
|
|
343
|
+
return response.json()
|
|
344
|
+
except ValueError:
|
|
345
|
+
return None
|
|
346
|
+
|
|
347
|
+
def organization_search(
|
|
348
|
+
self,
|
|
349
|
+
organization_num_employees_ranges_: list[str] | None = None,
|
|
350
|
+
organization_locations_: list[str] | None = None,
|
|
351
|
+
organization_not_locations_: list[str] | None = None,
|
|
352
|
+
revenue_range_min: int | None = None,
|
|
353
|
+
revenue_range_max: int | None = None,
|
|
354
|
+
currently_using_any_of_technology_uids_: list[str] | None = None,
|
|
355
|
+
q_organization_keyword_tags_: list[str] | None = None,
|
|
356
|
+
q_organization_name: str | None = None,
|
|
357
|
+
organization_ids_: list[str] | None = None,
|
|
358
|
+
page: int | None = None,
|
|
359
|
+
per_page: int | None = None,
|
|
360
|
+
) -> dict[str, Any]:
|
|
361
|
+
"""
|
|
362
|
+
Searches mixed companies based on various criteria such as employee ranges, locations, revenue range, technology usage, keyword tags, organization names, and IDs, supporting pagination.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
organization_num_employees_ranges_ (array): Specify company employee headcount ranges by listing strings like "1,10" or "250,500"; multiple ranges are allowed.
|
|
366
|
+
organization_locations_ (array): The organization_locations[] parameter filters companies by their headquarters' location—city, state, or country; multiple office locations are ignored, and to exclude locations, use organization_not_locations.
|
|
367
|
+
organization_not_locations_ (array): Exclude companies headquartered in specified locations such as cities, US states, or countries from search results to avoid prospecting in unwanted territories (e.g., `ireland`, `minnesota`, `seoul`).
|
|
368
|
+
revenue_range_min (integer): Sets the minimum revenue value for filtering organizations; enter only digits, without currency symbols, commas, or decimals.
|
|
369
|
+
revenue_range_max (integer): Set the maximum organization revenue for search filtering as an integer without currency symbols, commas, or decimals; pair with `revenue_range[min]` to define a revenue range (e.g., 50000000).
|
|
370
|
+
currently_using_any_of_technology_uids_ (array): Filter organizations by the technologies they currently use from over 1,500 options, identified with underscores replacing spaces and periods as in the provided technology list.
|
|
371
|
+
q_organization_keyword_tags_ (array): Filter search results by specifying keywords related to company industries, services, or focus areas, such as "mining," "sales strategy," or "consulting," to return matching companies.
|
|
372
|
+
q_organization_name (string): Filters results to companies whose names contain the specified value (partial match allowed); unmatched names are excluded, regardless of other criteria.
|
|
373
|
+
organization_ids_ (array): The Apollo unique company IDs to filter search results by specific organizations; each ID corresponds to a company in the Apollo database, e.g., `5e66b6381e05b4008c8331b8`.
|
|
374
|
+
page (integer): The page number of Apollo data to retrieve, used with `per_page` to paginate results and optimize performance; for example, `4` returns the fourth page of results.
|
|
375
|
+
per_page (integer): The number of search results returned per page to limit response size and improve performance; use the `page` parameter to access additional pages. Example: `10`.
|
|
376
|
+
|
|
377
|
+
Returns:
|
|
378
|
+
dict[str, Any]: 200
|
|
379
|
+
|
|
380
|
+
Raises:
|
|
381
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
382
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
383
|
+
|
|
384
|
+
Tags:
|
|
385
|
+
Organizations
|
|
386
|
+
"""
|
|
387
|
+
request_body_data = None
|
|
388
|
+
url = f"{self.base_url}/mixed_companies/search"
|
|
389
|
+
query_params = {
|
|
390
|
+
k: v
|
|
391
|
+
for k, v in [
|
|
392
|
+
(
|
|
393
|
+
"organization_num_employees_ranges[]",
|
|
394
|
+
organization_num_employees_ranges_,
|
|
395
|
+
),
|
|
396
|
+
("organization_locations[]", organization_locations_),
|
|
397
|
+
("organization_not_locations[]", organization_not_locations_),
|
|
398
|
+
("revenue_range[min]", revenue_range_min),
|
|
399
|
+
("revenue_range[max]", revenue_range_max),
|
|
400
|
+
(
|
|
401
|
+
"currently_using_any_of_technology_uids[]",
|
|
402
|
+
currently_using_any_of_technology_uids_,
|
|
403
|
+
),
|
|
404
|
+
("q_organization_keyword_tags[]", q_organization_keyword_tags_),
|
|
405
|
+
("q_organization_name", q_organization_name),
|
|
406
|
+
("organization_ids[]", organization_ids_),
|
|
407
|
+
("page", page),
|
|
408
|
+
("per_page", per_page),
|
|
409
|
+
]
|
|
410
|
+
if v is not None
|
|
411
|
+
}
|
|
412
|
+
response = self._post(
|
|
413
|
+
url,
|
|
414
|
+
data=request_body_data,
|
|
415
|
+
params=query_params,
|
|
416
|
+
content_type="application/json",
|
|
417
|
+
)
|
|
418
|
+
response.raise_for_status()
|
|
419
|
+
if (
|
|
420
|
+
response.status_code == 204
|
|
421
|
+
or not response.content
|
|
422
|
+
or not response.text.strip()
|
|
423
|
+
):
|
|
424
|
+
return None
|
|
425
|
+
try:
|
|
426
|
+
return response.json()
|
|
427
|
+
except ValueError:
|
|
428
|
+
return None
|
|
429
|
+
|
|
430
|
+
def organization_jobs_postings(
|
|
431
|
+
self,
|
|
432
|
+
organization_id: str,
|
|
433
|
+
page: int | None = None,
|
|
434
|
+
per_page: int | None = None,
|
|
435
|
+
) -> dict[str, Any]:
|
|
436
|
+
"""
|
|
437
|
+
Retrieves a paginated list of job postings for a specified organization using the "GET" method, allowing optional pagination parameters for page and items per page.
|
|
438
|
+
|
|
439
|
+
Args:
|
|
440
|
+
organization_id (string): organization_id
|
|
441
|
+
page (integer): The page query parameter specifies which page of job postings to retrieve, used with per_page to paginate results and improve response performance.
|
|
442
|
+
per_page (integer): The number of results to return per page in the response, which improves performance by limiting data size; use the `page` parameter to access other pages. Example: 10
|
|
443
|
+
|
|
444
|
+
Returns:
|
|
445
|
+
dict[str, Any]: 200
|
|
446
|
+
|
|
447
|
+
Raises:
|
|
448
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
449
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
450
|
+
|
|
451
|
+
Tags:
|
|
452
|
+
Organizations
|
|
453
|
+
"""
|
|
454
|
+
if organization_id is None:
|
|
455
|
+
raise ValueError("Missing required parameter 'organization_id'.")
|
|
456
|
+
url = f"{self.base_url}/organizations/{organization_id}/job_postings"
|
|
457
|
+
query_params = {
|
|
458
|
+
k: v for k, v in [("page", page), ("per_page", per_page)] if v is not None
|
|
459
|
+
}
|
|
460
|
+
response = self._get(url, params=query_params)
|
|
461
|
+
response.raise_for_status()
|
|
462
|
+
if (
|
|
463
|
+
response.status_code == 204
|
|
464
|
+
or not response.content
|
|
465
|
+
or not response.text.strip()
|
|
466
|
+
):
|
|
467
|
+
return None
|
|
468
|
+
try:
|
|
469
|
+
return response.json()
|
|
470
|
+
except ValueError:
|
|
471
|
+
return None
|
|
472
|
+
|
|
473
|
+
def create_an_account(
|
|
474
|
+
self,
|
|
475
|
+
name: str | None = None,
|
|
476
|
+
domain: str | None = None,
|
|
477
|
+
owner_id: str | None = None,
|
|
478
|
+
account_stage_id: str | None = None,
|
|
479
|
+
phone: str | None = None,
|
|
480
|
+
raw_address: str | None = None,
|
|
481
|
+
) -> dict[str, Any]:
|
|
482
|
+
"""
|
|
483
|
+
Creates a new account resource using the provided query parameters such as name, domain, owner ID, account stage ID, phone, and raw address.
|
|
484
|
+
|
|
485
|
+
Args:
|
|
486
|
+
name (string): A unique, human-readable name for the new account, such as "The Irish Copywriters."
|
|
487
|
+
domain (string): The domain name for the account, entered without any prefixes like "www."; for example, use "apollo.io" or "microsoft.com".
|
|
488
|
+
owner_id (string): The unique identifier of the account owner within your team's Apollo account, required to assign ownership; retrieve valid user IDs using the Get a List of Users endpoint.
|
|
489
|
+
account_stage_id (string): Apollo ID of the account stage to assign the account to; otherwise, it defaults to your team's settings.
|
|
490
|
+
phone (string): The primary phone number for the account, which may be for headquarters, a branch, or a main contact; any format is accepted and sanitized for consistency in the response.
|
|
491
|
+
raw_address (string): Corporate location for the account, including city, state, and country, matched to a pre-defined location by Apollo.
|
|
492
|
+
|
|
493
|
+
Returns:
|
|
494
|
+
dict[str, Any]: 200
|
|
495
|
+
|
|
496
|
+
Raises:
|
|
497
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
498
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
499
|
+
|
|
500
|
+
Tags:
|
|
501
|
+
Accounts
|
|
502
|
+
"""
|
|
503
|
+
request_body_data = None
|
|
504
|
+
url = f"{self.base_url}/accounts"
|
|
505
|
+
query_params = {
|
|
506
|
+
k: v
|
|
507
|
+
for k, v in [
|
|
508
|
+
("name", name),
|
|
509
|
+
("domain", domain),
|
|
510
|
+
("owner_id", owner_id),
|
|
511
|
+
("account_stage_id", account_stage_id),
|
|
512
|
+
("phone", phone),
|
|
513
|
+
("raw_address", raw_address),
|
|
514
|
+
]
|
|
515
|
+
if v is not None
|
|
516
|
+
}
|
|
517
|
+
response = self._post(
|
|
518
|
+
url,
|
|
519
|
+
data=request_body_data,
|
|
520
|
+
params=query_params,
|
|
521
|
+
content_type="application/json",
|
|
522
|
+
)
|
|
523
|
+
response.raise_for_status()
|
|
524
|
+
if (
|
|
525
|
+
response.status_code == 204
|
|
526
|
+
or not response.content
|
|
527
|
+
or not response.text.strip()
|
|
528
|
+
):
|
|
529
|
+
return None
|
|
530
|
+
try:
|
|
531
|
+
return response.json()
|
|
532
|
+
except ValueError:
|
|
533
|
+
return None
|
|
534
|
+
|
|
535
|
+
def update_an_account(
|
|
536
|
+
self,
|
|
537
|
+
account_id: str,
|
|
538
|
+
name: str | None = None,
|
|
539
|
+
domain: str | None = None,
|
|
540
|
+
owner_id: str | None = None,
|
|
541
|
+
account_stage_id: str | None = None,
|
|
542
|
+
raw_address: str | None = None,
|
|
543
|
+
phone: str | None = None,
|
|
544
|
+
) -> dict[str, Any]:
|
|
545
|
+
"""
|
|
546
|
+
Updates an account identified by `{account_id}` with specified parameters such as `name`, `domain`, `owner_id`, `account_stage_id`, `raw_address`, and `phone`, returning a status message upon successful modification.
|
|
547
|
+
|
|
548
|
+
Args:
|
|
549
|
+
account_id (string): account_id
|
|
550
|
+
name (string): Specify the account's human-readable name. Example: "The Fast Irish Copywriters"
|
|
551
|
+
domain (string): Specify the account's domain name to update, excluding any prefixes like "www."; use only the base domain such as "example.com" or "company.org".
|
|
552
|
+
owner_id (string): The ID of the user within your Apollo team to assign as the account owner; changing this updates the account owner. Retrieve valid user IDs via the Get a List of Users endpoint.
|
|
553
|
+
account_stage_id (string): The Apollo ID of the account stage to assign or update the account's stage; omit to auto-assign based on your team's default settings. Use List Account Stages to find IDs.
|
|
554
|
+
raw_address (string): Update the corporate location for the account. Provide a city, state, and country to match our pre-defined locations. Examples: `Belfield, Dublin 4, Ireland`; `Dallas, United States`.
|
|
555
|
+
phone (string): Update the account's primary phone number, which may be the corporate headquarters, a branch, or a direct contact; input in any format, sanitized and returned formatted.
|
|
556
|
+
|
|
557
|
+
Returns:
|
|
558
|
+
dict[str, Any]: 200
|
|
559
|
+
|
|
560
|
+
Raises:
|
|
561
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
562
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
563
|
+
|
|
564
|
+
Tags:
|
|
565
|
+
Accounts
|
|
566
|
+
"""
|
|
567
|
+
if account_id is None:
|
|
568
|
+
raise ValueError("Missing required parameter 'account_id'.")
|
|
569
|
+
request_body_data = None
|
|
570
|
+
url = f"{self.base_url}/accounts/{account_id}"
|
|
571
|
+
query_params = {
|
|
572
|
+
k: v
|
|
573
|
+
for k, v in [
|
|
574
|
+
("name", name),
|
|
575
|
+
("domain", domain),
|
|
576
|
+
("owner_id", owner_id),
|
|
577
|
+
("account_stage_id", account_stage_id),
|
|
578
|
+
("raw_address", raw_address),
|
|
579
|
+
("phone", phone),
|
|
580
|
+
]
|
|
581
|
+
if v is not None
|
|
582
|
+
}
|
|
583
|
+
response = self._put(
|
|
584
|
+
url,
|
|
585
|
+
data=request_body_data,
|
|
586
|
+
params=query_params,
|
|
587
|
+
content_type="application/json",
|
|
588
|
+
)
|
|
589
|
+
response.raise_for_status()
|
|
590
|
+
if (
|
|
591
|
+
response.status_code == 204
|
|
592
|
+
or not response.content
|
|
593
|
+
or not response.text.strip()
|
|
594
|
+
):
|
|
595
|
+
return None
|
|
596
|
+
try:
|
|
597
|
+
return response.json()
|
|
598
|
+
except ValueError:
|
|
599
|
+
return None
|
|
600
|
+
|
|
601
|
+
def search_for_accounts(
|
|
602
|
+
self,
|
|
603
|
+
q_organization_name: str | None = None,
|
|
604
|
+
account_stage_ids_: list[str] | None = None,
|
|
605
|
+
sort_by_field: str | None = None,
|
|
606
|
+
sort_ascending: bool | None = None,
|
|
607
|
+
page: int | None = None,
|
|
608
|
+
per_page: int | None = None,
|
|
609
|
+
) -> dict[str, Any]:
|
|
610
|
+
"""
|
|
611
|
+
Searches for accounts based on organization name, account stage IDs, sorting, and pagination parameters, returning matching results.
|
|
612
|
+
|
|
613
|
+
Args:
|
|
614
|
+
q_organization_name (string): Search for accounts by name using keywords. Matches part of the name, e.g., 'marketing' returns 'NY Marketing Unlimited'.
|
|
615
|
+
account_stage_ids_ (array): Specify Apollo IDs for account stages to include in search results. Multiple stages will match any of them.
|
|
616
|
+
sort_by_field (string): Sort matching accounts by one of these fields: `account_last_activity_date` (most recent activity first), `account_created_at` (newest accounts first), or `account_updated_at` (most recently updated first).
|
|
617
|
+
sort_ascending (boolean): Sort results in ascending order using the specified `sort_by_field`.
|
|
618
|
+
page (integer): The page number of the Apollo data to retrieve, used with the `per_page` parameter to paginate search results and optimize endpoint performance; for example, `4`.
|
|
619
|
+
per_page (integer): The number of search results returned per page to improve response performance; use the `page` parameter to access additional pages. Example value: `10`.
|
|
620
|
+
|
|
621
|
+
Returns:
|
|
622
|
+
dict[str, Any]: 200
|
|
623
|
+
|
|
624
|
+
Raises:
|
|
625
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
626
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
627
|
+
|
|
628
|
+
Tags:
|
|
629
|
+
Accounts
|
|
630
|
+
"""
|
|
631
|
+
request_body_data = None
|
|
632
|
+
url = f"{self.base_url}/accounts/search"
|
|
633
|
+
query_params = {
|
|
634
|
+
k: v
|
|
635
|
+
for k, v in [
|
|
636
|
+
("q_organization_name", q_organization_name),
|
|
637
|
+
("account_stage_ids[]", account_stage_ids_),
|
|
638
|
+
("sort_by_field", sort_by_field),
|
|
639
|
+
("sort_ascending", sort_ascending),
|
|
640
|
+
("page", page),
|
|
641
|
+
("per_page", per_page),
|
|
642
|
+
]
|
|
643
|
+
if v is not None
|
|
644
|
+
}
|
|
645
|
+
response = self._post(
|
|
646
|
+
url,
|
|
647
|
+
data=request_body_data,
|
|
648
|
+
params=query_params,
|
|
649
|
+
content_type="application/json",
|
|
650
|
+
)
|
|
651
|
+
response.raise_for_status()
|
|
652
|
+
if (
|
|
653
|
+
response.status_code == 204
|
|
654
|
+
or not response.content
|
|
655
|
+
or not response.text.strip()
|
|
656
|
+
):
|
|
657
|
+
return None
|
|
658
|
+
try:
|
|
659
|
+
return response.json()
|
|
660
|
+
except ValueError:
|
|
661
|
+
return None
|
|
662
|
+
|
|
663
|
+
def update_account_stage(
|
|
664
|
+
self, account_ids_: list[str], account_stage_id: str
|
|
665
|
+
) -> dict[str, Any]:
|
|
666
|
+
"""
|
|
667
|
+
Updates multiple account records in bulk by their specified IDs, assigning each to the given account stage ID.
|
|
668
|
+
|
|
669
|
+
Args:
|
|
670
|
+
account_ids_ (array): The Apollo ID(s) of the account(s) to update; obtain these IDs by using the Search for Accounts endpoint and referencing each account’s `id` value.
|
|
671
|
+
account_stage_id (string): Specify the Apollo account stage ID to assign to accounts; find available IDs via the List Account Stages endpoint.
|
|
672
|
+
|
|
673
|
+
Returns:
|
|
674
|
+
dict[str, Any]: 200
|
|
675
|
+
|
|
676
|
+
Raises:
|
|
677
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
678
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
679
|
+
|
|
680
|
+
Tags:
|
|
681
|
+
Accounts
|
|
682
|
+
"""
|
|
683
|
+
request_body_data = None
|
|
684
|
+
url = f"{self.base_url}/accounts/bulk_update"
|
|
685
|
+
query_params = {
|
|
686
|
+
k: v
|
|
687
|
+
for k, v in [
|
|
688
|
+
("account_ids[]", account_ids_),
|
|
689
|
+
("account_stage_id", account_stage_id),
|
|
690
|
+
]
|
|
691
|
+
if v is not None
|
|
692
|
+
}
|
|
693
|
+
response = self._post(
|
|
694
|
+
url,
|
|
695
|
+
data=request_body_data,
|
|
696
|
+
params=query_params,
|
|
697
|
+
content_type="application/json",
|
|
698
|
+
)
|
|
699
|
+
response.raise_for_status()
|
|
700
|
+
if (
|
|
701
|
+
response.status_code == 204
|
|
702
|
+
or not response.content
|
|
703
|
+
or not response.text.strip()
|
|
704
|
+
):
|
|
705
|
+
return None
|
|
706
|
+
try:
|
|
707
|
+
return response.json()
|
|
708
|
+
except ValueError:
|
|
709
|
+
return None
|
|
710
|
+
|
|
711
|
+
def update_account_ownership(
|
|
712
|
+
self, account_ids_: list[str], owner_id: str
|
|
713
|
+
) -> dict[str, Any]:
|
|
714
|
+
"""
|
|
715
|
+
Updates the owners of multiple accounts by assigning a specified owner ID to the given list of account IDs.
|
|
716
|
+
|
|
717
|
+
Args:
|
|
718
|
+
account_ids_ (array): The Apollo IDs of the accounts to assign new owners; obtain these IDs by using the Search for Accounts endpoint and referencing each account's `id` value.
|
|
719
|
+
owner_id (string): The owner_id is the unique identifier of the user in your Apollo team who will be assigned as the owner of the specified accounts; retrieve user IDs via the Get a List of Users endpoint.
|
|
720
|
+
|
|
721
|
+
Returns:
|
|
722
|
+
dict[str, Any]: 200
|
|
723
|
+
|
|
724
|
+
Raises:
|
|
725
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
726
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
727
|
+
|
|
728
|
+
Tags:
|
|
729
|
+
Accounts
|
|
730
|
+
"""
|
|
731
|
+
request_body_data = None
|
|
732
|
+
url = f"{self.base_url}/accounts/update_owners"
|
|
733
|
+
query_params = {
|
|
734
|
+
k: v
|
|
735
|
+
for k, v in [("account_ids[]", account_ids_), ("owner_id", owner_id)]
|
|
736
|
+
if v is not None
|
|
737
|
+
}
|
|
738
|
+
response = self._post(
|
|
739
|
+
url,
|
|
740
|
+
data=request_body_data,
|
|
741
|
+
params=query_params,
|
|
742
|
+
content_type="application/json",
|
|
743
|
+
)
|
|
744
|
+
response.raise_for_status()
|
|
745
|
+
if (
|
|
746
|
+
response.status_code == 204
|
|
747
|
+
or not response.content
|
|
748
|
+
or not response.text.strip()
|
|
749
|
+
):
|
|
750
|
+
return None
|
|
751
|
+
try:
|
|
752
|
+
return response.json()
|
|
753
|
+
except ValueError:
|
|
754
|
+
return None
|
|
755
|
+
|
|
756
|
+
def list_account_stages(self) -> dict[str, Any]:
|
|
757
|
+
"""
|
|
758
|
+
Retrieves a list of account stages.
|
|
759
|
+
|
|
760
|
+
Returns:
|
|
761
|
+
dict[str, Any]: 200
|
|
762
|
+
|
|
763
|
+
Raises:
|
|
764
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
765
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
766
|
+
|
|
767
|
+
Tags:
|
|
768
|
+
Accounts
|
|
769
|
+
"""
|
|
770
|
+
url = f"{self.base_url}/account_stages"
|
|
771
|
+
query_params = {}
|
|
772
|
+
response = self._get(url, params=query_params)
|
|
773
|
+
response.raise_for_status()
|
|
774
|
+
if (
|
|
775
|
+
response.status_code == 204
|
|
776
|
+
or not response.content
|
|
777
|
+
or not response.text.strip()
|
|
778
|
+
):
|
|
779
|
+
return None
|
|
780
|
+
try:
|
|
781
|
+
return response.json()
|
|
782
|
+
except ValueError:
|
|
783
|
+
return None
|
|
784
|
+
|
|
785
|
+
def create_a_contact(
|
|
786
|
+
self,
|
|
787
|
+
first_name: str | None = None,
|
|
788
|
+
last_name: str | None = None,
|
|
789
|
+
organization_name: str | None = None,
|
|
790
|
+
title: str | None = None,
|
|
791
|
+
account_id: str | None = None,
|
|
792
|
+
email: str | None = None,
|
|
793
|
+
website_url: str | None = None,
|
|
794
|
+
label_names_: list[str] | None = None,
|
|
795
|
+
contact_stage_id: str | None = None,
|
|
796
|
+
present_raw_address: str | None = None,
|
|
797
|
+
direct_phone: str | None = None,
|
|
798
|
+
corporate_phone: str | None = None,
|
|
799
|
+
mobile_phone: str | None = None,
|
|
800
|
+
home_phone: str | None = None,
|
|
801
|
+
other_phone: str | None = None,
|
|
802
|
+
) -> dict[str, Any]:
|
|
803
|
+
"""
|
|
804
|
+
Creates a new contact with specified details such as name, organization, contact information, and labels.
|
|
805
|
+
|
|
806
|
+
Args:
|
|
807
|
+
first_name (string): The first name of the contact to be created, provided as a readable human name (e.g., "Tim"). This value identifies the contact in the system.
|
|
808
|
+
last_name (string): The last name of the contact to create, ideally a human-readable full surname.
|
|
809
|
+
organization_name (string): The current employer's exact company name for the contact, used to ensure correct assignment in the Apollo contact base; verify using the Organization Search endpoint if needed.
|
|
810
|
+
title (string): The current job title of the contact, such as 'senior research analyst'.
|
|
811
|
+
account_id (string): Unique Apollo ID for the account to assign the contact, retrieved from Organization Search or enrichment endpoints.
|
|
812
|
+
email (string): String: The email address of the contact; must be a valid, properly formatted email, e.g., example@email.com.
|
|
813
|
+
website_url (string): The full corporate website URL of the contact's current employer, including the domain (e.g., .com), without any subdirectories or social media links, to ensure accurate data enrichment.
|
|
814
|
+
label_names_ (array): Add contact to existing or new lists using any list name; unmatched names create new lists automatically. Example: "2024 big marketing conference attendees".
|
|
815
|
+
contact_stage_id (string): Specify the Apollo contact stage ID to assign the contact; if omitted, Apollo will assign a default stage per your settings. Example: 6095a710bd01d100a506d4ae
|
|
816
|
+
present_raw_address (string): The contact's personal location, which can include city, state, and country, matched to the closest predefined location for accurate identification (e.g., "Atlanta, United States").
|
|
817
|
+
direct_phone (string): Primary phone number for the contact. Enter in any format; Apollo sanitizes it. Examples: `555-303-1234`, `+44 7911 123456`.
|
|
818
|
+
corporate_phone (string): The direct work/office phone number for the contact (not the headquarters), which is sanitized and can be provided in any format; examples: 555-303-1234 or +44 7911 123456.
|
|
819
|
+
mobile_phone (string): Mobile phone number for the contact. Enter in any format; Apollo sanitizes and returns the standardized number.
|
|
820
|
+
home_phone (string): Enter the contact's home phone number in any format; Apollo sanitizes and returns the standardized value in the response.
|
|
821
|
+
other_phone (string): Specifies an alternative or unknown phone type for the contact; Apollo accepts any format and returns sanitized numbers in the response, e.g., '555-303-1234', '+44 7911 123456'.
|
|
822
|
+
|
|
823
|
+
Returns:
|
|
824
|
+
dict[str, Any]: 200
|
|
825
|
+
|
|
826
|
+
Raises:
|
|
827
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
828
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
829
|
+
|
|
830
|
+
Tags:
|
|
831
|
+
Contacts, important
|
|
832
|
+
"""
|
|
833
|
+
request_body_data = None
|
|
834
|
+
url = f"{self.base_url}/contacts"
|
|
835
|
+
query_params = {
|
|
836
|
+
k: v
|
|
837
|
+
for k, v in [
|
|
838
|
+
("first_name", first_name),
|
|
839
|
+
("last_name", last_name),
|
|
840
|
+
("organization_name", organization_name),
|
|
841
|
+
("title", title),
|
|
842
|
+
("account_id", account_id),
|
|
843
|
+
("email", email),
|
|
844
|
+
("website_url", website_url),
|
|
845
|
+
("label_names[]", label_names_),
|
|
846
|
+
("contact_stage_id", contact_stage_id),
|
|
847
|
+
("present_raw_address", present_raw_address),
|
|
848
|
+
("direct_phone", direct_phone),
|
|
849
|
+
("corporate_phone", corporate_phone),
|
|
850
|
+
("mobile_phone", mobile_phone),
|
|
851
|
+
("home_phone", home_phone),
|
|
852
|
+
("other_phone", other_phone),
|
|
853
|
+
]
|
|
854
|
+
if v is not None
|
|
855
|
+
}
|
|
856
|
+
response = self._post(
|
|
857
|
+
url,
|
|
858
|
+
data=request_body_data,
|
|
859
|
+
params=query_params,
|
|
860
|
+
content_type="application/json",
|
|
861
|
+
)
|
|
862
|
+
response.raise_for_status()
|
|
863
|
+
if (
|
|
864
|
+
response.status_code == 204
|
|
865
|
+
or not response.content
|
|
866
|
+
or not response.text.strip()
|
|
867
|
+
):
|
|
868
|
+
return None
|
|
869
|
+
try:
|
|
870
|
+
return response.json()
|
|
871
|
+
except ValueError:
|
|
872
|
+
return None
|
|
873
|
+
|
|
874
|
+
def update_a_contact(
|
|
875
|
+
self,
|
|
876
|
+
contact_id: str,
|
|
877
|
+
first_name: str | None = None,
|
|
878
|
+
last_name: str | None = None,
|
|
879
|
+
organization_name: str | None = None,
|
|
880
|
+
title: str | None = None,
|
|
881
|
+
account_id: str | None = None,
|
|
882
|
+
email: str | None = None,
|
|
883
|
+
website_url: str | None = None,
|
|
884
|
+
label_names_: list[str] | None = None,
|
|
885
|
+
contact_stage_id: str | None = None,
|
|
886
|
+
present_raw_address: str | None = None,
|
|
887
|
+
direct_phone: str | None = None,
|
|
888
|
+
corporate_phone: str | None = None,
|
|
889
|
+
mobile_phone: str | None = None,
|
|
890
|
+
home_phone: str | None = None,
|
|
891
|
+
other_phone: str | None = None,
|
|
892
|
+
) -> dict[str, Any]:
|
|
893
|
+
"""
|
|
894
|
+
Updates or replaces the details of a specific contact identified by contact_id using the provided parameters as new values for the contact record.
|
|
895
|
+
|
|
896
|
+
Args:
|
|
897
|
+
contact_id (string): contact_id
|
|
898
|
+
first_name (string): Update the contact's first name with a human-readable string representing their given name, such as "Tim".
|
|
899
|
+
last_name (string): Sets the contact's last name; expects a readable value (e.g. 'Zheng') for identification purposes.
|
|
900
|
+
organization_name (string): Update the contact's current employer name to match the exact company name in the Apollo database for accurate assignment. Example: `apollo`.
|
|
901
|
+
title (string): Specify the new job title for the contact, e.g., "senior research analyst."
|
|
902
|
+
account_id (string): Unique Apollo ID for updating the account assigned to a contact. Use Organization Search to find account IDs for enriched companies.
|
|
903
|
+
email (string): Update the contact's email address with a valid, unique email string (e.g., example@email.com); duplicate emails will cause an error response.
|
|
904
|
+
website_url (string): Update the full corporate website URL for the contact’s current employer, including the domain (e.g., .com) but excluding any subdirectories or social media links like LinkedIn, to ensure accurate data enrichment.
|
|
905
|
+
label_names_ (array): Update lists the contact belongs to in your Apollo account. If a list does not exist, Apollo creates it. Adding lists removes existing ones unless they are included again.
|
|
906
|
+
contact_stage_id (string): Specifies the Apollo contact stage ID; use this to assign or update the contact stage, available via List Contact Stages. Example: 6095a710bd01d100a506d4af.
|
|
907
|
+
present_raw_address (string): Set the contact's location by providing a city, state, and country, which will be matched to a predefined location.
|
|
908
|
+
direct_phone (string): Update the contact's primary phone number in any format; Apollo automatically sanitizes and standardizes the number, which is returned in the response for confirmation.
|
|
909
|
+
corporate_phone (string): Update the direct office phone number for the contact at their employer; Apollo sanitizes all formats and the cleaned number appears in the response.
|
|
910
|
+
mobile_phone (string): Sets or updates the contact's mobile phone number; accepts any format—Apollo sanitizes and returns the standardized version in the response.
|
|
911
|
+
home_phone (string): Specify the contact’s home phone number; Apollo accepts any format, sanitizes the input, and returns the clean version in the response.
|
|
912
|
+
other_phone (string): Update an alternative or unspecified phone number for the contact; Apollo automatically sanitizes any phone format, with the cleaned number shown in the response.
|
|
913
|
+
|
|
914
|
+
Returns:
|
|
915
|
+
dict[str, Any]: 200
|
|
916
|
+
|
|
917
|
+
Raises:
|
|
918
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
919
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
920
|
+
|
|
921
|
+
Tags:
|
|
922
|
+
Contacts
|
|
923
|
+
"""
|
|
924
|
+
if contact_id is None:
|
|
925
|
+
raise ValueError("Missing required parameter 'contact_id'.")
|
|
926
|
+
request_body_data = None
|
|
927
|
+
url = f"{self.base_url}/contacts/{contact_id}"
|
|
928
|
+
query_params = {
|
|
929
|
+
k: v
|
|
930
|
+
for k, v in [
|
|
931
|
+
("first_name", first_name),
|
|
932
|
+
("last_name", last_name),
|
|
933
|
+
("organization_name", organization_name),
|
|
934
|
+
("title", title),
|
|
935
|
+
("account_id", account_id),
|
|
936
|
+
("email", email),
|
|
937
|
+
("website_url", website_url),
|
|
938
|
+
("label_names[]", label_names_),
|
|
939
|
+
("contact_stage_id", contact_stage_id),
|
|
940
|
+
("present_raw_address", present_raw_address),
|
|
941
|
+
("direct_phone", direct_phone),
|
|
942
|
+
("corporate_phone", corporate_phone),
|
|
943
|
+
("mobile_phone", mobile_phone),
|
|
944
|
+
("home_phone", home_phone),
|
|
945
|
+
("other_phone", other_phone),
|
|
946
|
+
]
|
|
947
|
+
if v is not None
|
|
948
|
+
}
|
|
949
|
+
response = self._put(
|
|
950
|
+
url,
|
|
951
|
+
data=request_body_data,
|
|
952
|
+
params=query_params,
|
|
953
|
+
content_type="application/json",
|
|
954
|
+
)
|
|
955
|
+
response.raise_for_status()
|
|
956
|
+
if (
|
|
957
|
+
response.status_code == 204
|
|
958
|
+
or not response.content
|
|
959
|
+
or not response.text.strip()
|
|
960
|
+
):
|
|
961
|
+
return None
|
|
962
|
+
try:
|
|
963
|
+
return response.json()
|
|
964
|
+
except ValueError:
|
|
965
|
+
return None
|
|
966
|
+
|
|
967
|
+
def search_for_contacts(
|
|
968
|
+
self,
|
|
969
|
+
q_keywords: str | None = None,
|
|
970
|
+
contact_stage_ids_: list[str] | None = None,
|
|
971
|
+
sort_by_field: str | None = None,
|
|
972
|
+
sort_ascending: bool | None = None,
|
|
973
|
+
per_page: int | None = None,
|
|
974
|
+
page: int | None = None,
|
|
975
|
+
) -> dict[str, Any]:
|
|
976
|
+
"""
|
|
977
|
+
Searches contacts based on keywords, contact stage IDs, sorting, and pagination parameters, returning a filtered and sorted list of contacts.
|
|
978
|
+
|
|
979
|
+
Args:
|
|
980
|
+
q_keywords (string): Narrow search results by adding keywords such as names, job titles, companies, or email addresses.
|
|
981
|
+
contact_stage_ids_ (array): The Apollo IDs of the contact stages to include in the search; multiple IDs return contacts matching any listed stage combined with other search filters.
|
|
982
|
+
sort_by_field (string): Specify which field to sort results by: contact_last_activity_date, contact_email_last_opened_at, contact_email_last_clicked_at, contact_created_at, or contact_updated_at.
|
|
983
|
+
sort_ascending (boolean): Set to `true` to sort matching contacts in ascending order, but only if the `sort_by_field` parameter is specified; otherwise, sorting is ignored.
|
|
984
|
+
per_page (integer): Specifies the number of results to return per page, enhancing search result navigation and performance.
|
|
985
|
+
page (integer): Page size for search results; limits the number of results per page to improve performance.
|
|
986
|
+
|
|
987
|
+
Returns:
|
|
988
|
+
dict[str, Any]: 200
|
|
989
|
+
|
|
990
|
+
Raises:
|
|
991
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
992
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
993
|
+
|
|
994
|
+
Tags:
|
|
995
|
+
Contacts, important
|
|
996
|
+
"""
|
|
997
|
+
request_body_data = None
|
|
998
|
+
url = f"{self.base_url}/contacts/search"
|
|
999
|
+
query_params = {
|
|
1000
|
+
k: v
|
|
1001
|
+
for k, v in [
|
|
1002
|
+
("q_keywords", q_keywords),
|
|
1003
|
+
("contact_stage_ids[]", contact_stage_ids_),
|
|
1004
|
+
("sort_by_field", sort_by_field),
|
|
1005
|
+
("sort_ascending", sort_ascending),
|
|
1006
|
+
("per_page", per_page),
|
|
1007
|
+
("page", page),
|
|
1008
|
+
]
|
|
1009
|
+
if v is not None
|
|
1010
|
+
}
|
|
1011
|
+
response = self._post(
|
|
1012
|
+
url,
|
|
1013
|
+
data=request_body_data,
|
|
1014
|
+
params=query_params,
|
|
1015
|
+
content_type="application/json",
|
|
1016
|
+
)
|
|
1017
|
+
response.raise_for_status()
|
|
1018
|
+
if (
|
|
1019
|
+
response.status_code == 204
|
|
1020
|
+
or not response.content
|
|
1021
|
+
or not response.text.strip()
|
|
1022
|
+
):
|
|
1023
|
+
return None
|
|
1024
|
+
try:
|
|
1025
|
+
return response.json()
|
|
1026
|
+
except ValueError:
|
|
1027
|
+
return None
|
|
1028
|
+
|
|
1029
|
+
def update_contact_stage(
|
|
1030
|
+
self, contact_ids_: list[str], contact_stage_id: str
|
|
1031
|
+
) -> dict[str, Any]:
|
|
1032
|
+
"""
|
|
1033
|
+
Updates the stage of multiple contacts by specifying their IDs and the new contact stage ID via a POST request.
|
|
1034
|
+
|
|
1035
|
+
Args:
|
|
1036
|
+
contact_ids_ (array): The Apollo contact IDs to update, provided as an array of strings; obtain these IDs from the Search for Contacts endpoint's `id` field. Example: `66e34b81740c50074e3d1bd4`
|
|
1037
|
+
contact_stage_id (string): The Apollo ID of the contact stage to assign to contacts; retrieve valid IDs via the List Contact Stages endpoint. Example: `6095a710bd01d100a506d4af`.
|
|
1038
|
+
|
|
1039
|
+
Returns:
|
|
1040
|
+
dict[str, Any]: 200
|
|
1041
|
+
|
|
1042
|
+
Raises:
|
|
1043
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1044
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1045
|
+
|
|
1046
|
+
Tags:
|
|
1047
|
+
Contacts
|
|
1048
|
+
"""
|
|
1049
|
+
request_body_data = None
|
|
1050
|
+
url = f"{self.base_url}/contacts/update_stages"
|
|
1051
|
+
query_params = {
|
|
1052
|
+
k: v
|
|
1053
|
+
for k, v in [
|
|
1054
|
+
("contact_ids[]", contact_ids_),
|
|
1055
|
+
("contact_stage_id", contact_stage_id),
|
|
1056
|
+
]
|
|
1057
|
+
if v is not None
|
|
1058
|
+
}
|
|
1059
|
+
response = self._post(
|
|
1060
|
+
url,
|
|
1061
|
+
data=request_body_data,
|
|
1062
|
+
params=query_params,
|
|
1063
|
+
content_type="application/json",
|
|
1064
|
+
)
|
|
1065
|
+
response.raise_for_status()
|
|
1066
|
+
if (
|
|
1067
|
+
response.status_code == 204
|
|
1068
|
+
or not response.content
|
|
1069
|
+
or not response.text.strip()
|
|
1070
|
+
):
|
|
1071
|
+
return None
|
|
1072
|
+
try:
|
|
1073
|
+
return response.json()
|
|
1074
|
+
except ValueError:
|
|
1075
|
+
return None
|
|
1076
|
+
|
|
1077
|
+
def update_contact_ownership(
|
|
1078
|
+
self, contact_ids_: list[str], owner_id: str
|
|
1079
|
+
) -> dict[str, Any]:
|
|
1080
|
+
"""
|
|
1081
|
+
Updates the owners of specified contacts by assigning a new owner ID to the provided list of contact IDs.
|
|
1082
|
+
|
|
1083
|
+
Args:
|
|
1084
|
+
contact_ids_ (array): The Apollo contact IDs to update ownership for; provide one or more IDs obtained from the Search for Contacts endpoint to assign new owners.
|
|
1085
|
+
owner_id (string): Specifies the Apollo account user ID to assign as owner for the contacts; find user IDs via the Get List of Users endpoint. Example: 66302798d03b9601c7934ebf.
|
|
1086
|
+
|
|
1087
|
+
Returns:
|
|
1088
|
+
dict[str, Any]: 200
|
|
1089
|
+
|
|
1090
|
+
Raises:
|
|
1091
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1092
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1093
|
+
|
|
1094
|
+
Tags:
|
|
1095
|
+
Contacts
|
|
1096
|
+
"""
|
|
1097
|
+
request_body_data = None
|
|
1098
|
+
url = f"{self.base_url}/contacts/update_owners"
|
|
1099
|
+
query_params = {
|
|
1100
|
+
k: v
|
|
1101
|
+
for k, v in [("contact_ids[]", contact_ids_), ("owner_id", owner_id)]
|
|
1102
|
+
if v is not None
|
|
1103
|
+
}
|
|
1104
|
+
response = self._post(
|
|
1105
|
+
url,
|
|
1106
|
+
data=request_body_data,
|
|
1107
|
+
params=query_params,
|
|
1108
|
+
content_type="application/json",
|
|
1109
|
+
)
|
|
1110
|
+
response.raise_for_status()
|
|
1111
|
+
if (
|
|
1112
|
+
response.status_code == 204
|
|
1113
|
+
or not response.content
|
|
1114
|
+
or not response.text.strip()
|
|
1115
|
+
):
|
|
1116
|
+
return None
|
|
1117
|
+
try:
|
|
1118
|
+
return response.json()
|
|
1119
|
+
except ValueError:
|
|
1120
|
+
return None
|
|
1121
|
+
|
|
1122
|
+
def list_contact_stages(self) -> Any:
|
|
1123
|
+
"""
|
|
1124
|
+
Retrieves a list of all available contact stage IDs from the Apollo account[2][4].
|
|
1125
|
+
|
|
1126
|
+
Returns:
|
|
1127
|
+
Any: 200
|
|
1128
|
+
|
|
1129
|
+
Raises:
|
|
1130
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1131
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1132
|
+
|
|
1133
|
+
Tags:
|
|
1134
|
+
Contacts
|
|
1135
|
+
"""
|
|
1136
|
+
url = f"{self.base_url}/contact_stages"
|
|
1137
|
+
query_params = {}
|
|
1138
|
+
response = self._get(url, params=query_params)
|
|
1139
|
+
response.raise_for_status()
|
|
1140
|
+
if (
|
|
1141
|
+
response.status_code == 204
|
|
1142
|
+
or not response.content
|
|
1143
|
+
or not response.text.strip()
|
|
1144
|
+
):
|
|
1145
|
+
return None
|
|
1146
|
+
try:
|
|
1147
|
+
return response.json()
|
|
1148
|
+
except ValueError:
|
|
1149
|
+
return None
|
|
1150
|
+
|
|
1151
|
+
def create_deal(
|
|
1152
|
+
self,
|
|
1153
|
+
name: str,
|
|
1154
|
+
owner_id: str | None = None,
|
|
1155
|
+
account_id: str | None = None,
|
|
1156
|
+
amount: str | None = None,
|
|
1157
|
+
opportunity_stage_id: str | None = None,
|
|
1158
|
+
closed_date: str | None = None,
|
|
1159
|
+
) -> dict[str, Any]:
|
|
1160
|
+
"""
|
|
1161
|
+
Creates a new opportunity with specified details such as name, owner, account, amount, stage, and closed date.
|
|
1162
|
+
|
|
1163
|
+
Args:
|
|
1164
|
+
name (string): Specify a short, descriptive, human-readable name for the opportunity or deal being created, such as "Massive Q3 Deal."
|
|
1165
|
+
owner_id (string): Specify the unique Apollo user ID (found via Get Users endpoint) responsible for the opportunity as the deal owner.
|
|
1166
|
+
account_id (string): The unique Apollo account ID for the company targeted in this deal; retrieve via Organization Search as organization_id—example: 5e66b6381e05b4008c8331b8.
|
|
1167
|
+
amount (string): The monetary value of the deal to create, entered as a numeric amount without commas or currency symbols; the currency is set automatically from your Apollo account settings.
|
|
1168
|
+
opportunity_stage_id (string): The unique identifier for the deal stage in your team's Apollo account; use the List Deal Stages endpoint to retrieve valid IDs for this parameter.
|
|
1169
|
+
closed_date (string): The estimated close date for the deal, in YYYY-MM-DD format.
|
|
1170
|
+
|
|
1171
|
+
Returns:
|
|
1172
|
+
dict[str, Any]: 200
|
|
1173
|
+
|
|
1174
|
+
Raises:
|
|
1175
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1176
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1177
|
+
|
|
1178
|
+
Tags:
|
|
1179
|
+
Deals
|
|
1180
|
+
"""
|
|
1181
|
+
request_body_data = None
|
|
1182
|
+
url = f"{self.base_url}/opportunities"
|
|
1183
|
+
query_params = {
|
|
1184
|
+
k: v
|
|
1185
|
+
for k, v in [
|
|
1186
|
+
("name", name),
|
|
1187
|
+
("owner_id", owner_id),
|
|
1188
|
+
("account_id", account_id),
|
|
1189
|
+
("amount", amount),
|
|
1190
|
+
("opportunity_stage_id", opportunity_stage_id),
|
|
1191
|
+
("closed_date", closed_date),
|
|
1192
|
+
]
|
|
1193
|
+
if v is not None
|
|
1194
|
+
}
|
|
1195
|
+
response = self._post(
|
|
1196
|
+
url,
|
|
1197
|
+
data=request_body_data,
|
|
1198
|
+
params=query_params,
|
|
1199
|
+
content_type="application/json",
|
|
1200
|
+
)
|
|
1201
|
+
response.raise_for_status()
|
|
1202
|
+
if (
|
|
1203
|
+
response.status_code == 204
|
|
1204
|
+
or not response.content
|
|
1205
|
+
or not response.text.strip()
|
|
1206
|
+
):
|
|
1207
|
+
return None
|
|
1208
|
+
try:
|
|
1209
|
+
return response.json()
|
|
1210
|
+
except ValueError:
|
|
1211
|
+
return None
|
|
1212
|
+
|
|
1213
|
+
def list_all_deals(
|
|
1214
|
+
self,
|
|
1215
|
+
sort_by_field: str | None = None,
|
|
1216
|
+
page: int | None = None,
|
|
1217
|
+
per_page: int | None = None,
|
|
1218
|
+
) -> dict[str, Any]:
|
|
1219
|
+
"""
|
|
1220
|
+
Searches and retrieves a paginated list of opportunities with optional sorting by a specified field.
|
|
1221
|
+
|
|
1222
|
+
Args:
|
|
1223
|
+
sort_by_field (string): Sort opportunities by one of the following: amount for highest deal values first, is_closed for closed deals first, or is_won for deals marked as won first.
|
|
1224
|
+
page (integer): The page query parameter specifies which page of results to retrieve when searching opportunities; use with `per_page` to paginate and optimize response performance.
|
|
1225
|
+
per_page (integer): The number of results returned per page in the search response; limiting this improves performance. Use the `page` parameter to access additional pages. Example: `10`.
|
|
1226
|
+
|
|
1227
|
+
Returns:
|
|
1228
|
+
dict[str, Any]: 200
|
|
1229
|
+
|
|
1230
|
+
Raises:
|
|
1231
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1232
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1233
|
+
|
|
1234
|
+
Tags:
|
|
1235
|
+
Deals, important
|
|
1236
|
+
"""
|
|
1237
|
+
url = f"{self.base_url}/opportunities/search"
|
|
1238
|
+
query_params = {
|
|
1239
|
+
k: v
|
|
1240
|
+
for k, v in [
|
|
1241
|
+
("sort_by_field", sort_by_field),
|
|
1242
|
+
("page", page),
|
|
1243
|
+
("per_page", per_page),
|
|
1244
|
+
]
|
|
1245
|
+
if v is not None
|
|
1246
|
+
}
|
|
1247
|
+
response = self._get(url, params=query_params)
|
|
1248
|
+
response.raise_for_status()
|
|
1249
|
+
if (
|
|
1250
|
+
response.status_code == 204
|
|
1251
|
+
or not response.content
|
|
1252
|
+
or not response.text.strip()
|
|
1253
|
+
):
|
|
1254
|
+
return None
|
|
1255
|
+
try:
|
|
1256
|
+
return response.json()
|
|
1257
|
+
except ValueError:
|
|
1258
|
+
return None
|
|
1259
|
+
|
|
1260
|
+
def update_deal(
|
|
1261
|
+
self,
|
|
1262
|
+
opportunity_id: str,
|
|
1263
|
+
owner_id: str | None = None,
|
|
1264
|
+
name: str | None = None,
|
|
1265
|
+
amount: str | None = None,
|
|
1266
|
+
opportunity_stage_id: str | None = None,
|
|
1267
|
+
closed_date: str | None = None,
|
|
1268
|
+
is_closed: bool | None = None,
|
|
1269
|
+
is_won: bool | None = None,
|
|
1270
|
+
source: str | None = None,
|
|
1271
|
+
account_id: str | None = None,
|
|
1272
|
+
) -> dict[str, Any]:
|
|
1273
|
+
"""
|
|
1274
|
+
Updates specific fields of an opportunity resource identified by opportunity_id using a PATCH request[2][4][5].
|
|
1275
|
+
|
|
1276
|
+
Args:
|
|
1277
|
+
opportunity_id (string): opportunity_id
|
|
1278
|
+
owner_id (string): The ID of the user within your Apollo team to assign as the new owner of the deal; use the List Users endpoint to find valid user IDs.
|
|
1279
|
+
name (string): Update the deal’s name with a clear, human-readable title that identifies the opportunity, such as "Massive Q3 Deal."
|
|
1280
|
+
amount (string): The monetary value of the deal to update; enter a numeric value without commas or currency symbols—currency is set by your Apollo account settings. Example: 55123478 represents $55,123,478 if USD.
|
|
1281
|
+
opportunity_stage_id (string): Unique ID of the deal stage to update an opportunity's status. Replace with a different ID to change the stage.
|
|
1282
|
+
closed_date (string): Update the estimated close date for the opportunity, which can be any past or future date, formatted as YYYY-MM-DD (e.g., 2025-10-30).
|
|
1283
|
+
is_closed (boolean): Set to true to mark the opportunity as closed, or omit/use false to keep it open.
|
|
1284
|
+
is_won (boolean): Set this parameter to `true` in the query to mark the opportunity as won and update the deal status accordingly.
|
|
1285
|
+
source (string): Update the source of the deal, e.g., '2024 InfoSec Conference', overriding the default 'api' source for API-created deals.
|
|
1286
|
+
account_id (string): Specify the unique account ID to associate or update the company linked to this opportunity; find IDs using the Organization Search endpoint.
|
|
1287
|
+
|
|
1288
|
+
Returns:
|
|
1289
|
+
dict[str, Any]: 200
|
|
1290
|
+
|
|
1291
|
+
Raises:
|
|
1292
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1293
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1294
|
+
|
|
1295
|
+
Tags:
|
|
1296
|
+
Deals
|
|
1297
|
+
"""
|
|
1298
|
+
if opportunity_id is None:
|
|
1299
|
+
raise ValueError("Missing required parameter 'opportunity_id'.")
|
|
1300
|
+
request_body_data = None
|
|
1301
|
+
url = f"{self.base_url}/opportunities/{opportunity_id}"
|
|
1302
|
+
query_params = {
|
|
1303
|
+
k: v
|
|
1304
|
+
for k, v in [
|
|
1305
|
+
("owner_id", owner_id),
|
|
1306
|
+
("name", name),
|
|
1307
|
+
("amount", amount),
|
|
1308
|
+
("opportunity_stage_id", opportunity_stage_id),
|
|
1309
|
+
("closed_date", closed_date),
|
|
1310
|
+
("is_closed", is_closed),
|
|
1311
|
+
("is_won", is_won),
|
|
1312
|
+
("source", source),
|
|
1313
|
+
("account_id", account_id),
|
|
1314
|
+
]
|
|
1315
|
+
if v is not None
|
|
1316
|
+
}
|
|
1317
|
+
response = self._patch(url, data=request_body_data, params=query_params)
|
|
1318
|
+
response.raise_for_status()
|
|
1319
|
+
if (
|
|
1320
|
+
response.status_code == 204
|
|
1321
|
+
or not response.content
|
|
1322
|
+
or not response.text.strip()
|
|
1323
|
+
):
|
|
1324
|
+
return None
|
|
1325
|
+
try:
|
|
1326
|
+
return response.json()
|
|
1327
|
+
except ValueError:
|
|
1328
|
+
return None
|
|
1329
|
+
|
|
1330
|
+
def list_deal_stages(self) -> dict[str, Any]:
|
|
1331
|
+
"""
|
|
1332
|
+
Retrieves a list of opportunity stages representing the different phases in the sales pipeline.
|
|
1333
|
+
|
|
1334
|
+
Returns:
|
|
1335
|
+
dict[str, Any]: 200
|
|
1336
|
+
|
|
1337
|
+
Raises:
|
|
1338
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1339
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1340
|
+
|
|
1341
|
+
Tags:
|
|
1342
|
+
Deals
|
|
1343
|
+
"""
|
|
1344
|
+
url = f"{self.base_url}/opportunity_stages"
|
|
1345
|
+
query_params = {}
|
|
1346
|
+
response = self._get(url, params=query_params)
|
|
1347
|
+
response.raise_for_status()
|
|
1348
|
+
if (
|
|
1349
|
+
response.status_code == 204
|
|
1350
|
+
or not response.content
|
|
1351
|
+
or not response.text.strip()
|
|
1352
|
+
):
|
|
1353
|
+
return None
|
|
1354
|
+
try:
|
|
1355
|
+
return response.json()
|
|
1356
|
+
except ValueError:
|
|
1357
|
+
return None
|
|
1358
|
+
|
|
1359
|
+
def add_contacts_to_sequence(
|
|
1360
|
+
self,
|
|
1361
|
+
sequence_id: str,
|
|
1362
|
+
emailer_campaign_id: str,
|
|
1363
|
+
contact_ids_: list[str],
|
|
1364
|
+
send_email_from_email_account_id: str,
|
|
1365
|
+
sequence_no_email: bool | None = None,
|
|
1366
|
+
sequence_unverified_email: bool | None = None,
|
|
1367
|
+
sequence_job_change: bool | None = None,
|
|
1368
|
+
sequence_active_in_other_campaigns: bool | None = None,
|
|
1369
|
+
sequence_finished_in_other_campaigns: bool | None = None,
|
|
1370
|
+
user_id: str | None = None,
|
|
1371
|
+
) -> dict[str, Any]:
|
|
1372
|
+
"""
|
|
1373
|
+
Adds specified contact IDs to an email campaign sequence, configuring how and when emails are sent to each contact and supporting various filtering options.
|
|
1374
|
+
|
|
1375
|
+
Args:
|
|
1376
|
+
sequence_id (string): sequence_id
|
|
1377
|
+
emailer_campaign_id (string): The emailer_campaign_id query parameter must match the sequence_id path parameter and represents the unique identifier of the email campaign to which contacts are being added.
|
|
1378
|
+
contact_ids_ (array): Apollo IDs of contacts to add to the sequence. Use the Search for Contacts endpoint to find IDs.
|
|
1379
|
+
send_email_from_email_account_id (string): The Apollo ID of the email account used to send emails to contacts added to the sequence; obtain this ID from the Get a List of Email Accounts endpoint.
|
|
1380
|
+
sequence_no_email (boolean): Add contacts to the sequence even if they lack an email address by setting this to `true`.
|
|
1381
|
+
sequence_unverified_email (boolean): Indicates whether to allow adding contacts with unverified email addresses to the sequence.
|
|
1382
|
+
sequence_job_change (boolean): Set to `true` to add contacts to the email sequence even if they have recently changed jobs, overriding any default restrictions on re-adding such contacts.
|
|
1383
|
+
sequence_active_in_other_campaigns (boolean): When true, allows adding contacts even if they are already in other sequences, regardless of those sequences’ status (active or paused).
|
|
1384
|
+
sequence_finished_in_other_campaigns (boolean): Set to `true` to add contacts to this sequence even if they have completed a different sequence and are marked as finished there.
|
|
1385
|
+
user_id (string): The user_id query parameter specifies the ID of the Apollo team user performing the action to add contacts to a sequence, which appears in the sequence's activity log to identify who added the contacts.
|
|
1386
|
+
|
|
1387
|
+
Returns:
|
|
1388
|
+
dict[str, Any]: 200
|
|
1389
|
+
|
|
1390
|
+
Raises:
|
|
1391
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1392
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1393
|
+
|
|
1394
|
+
Tags:
|
|
1395
|
+
Contacts
|
|
1396
|
+
"""
|
|
1397
|
+
if sequence_id is None:
|
|
1398
|
+
raise ValueError("Missing required parameter 'sequence_id'.")
|
|
1399
|
+
request_body_data = None
|
|
1400
|
+
url = f"{self.base_url}/emailer_campaigns/{sequence_id}/add_contact_ids"
|
|
1401
|
+
query_params = {
|
|
1402
|
+
k: v
|
|
1403
|
+
for k, v in [
|
|
1404
|
+
("emailer_campaign_id", emailer_campaign_id),
|
|
1405
|
+
("contact_ids[]", contact_ids_),
|
|
1406
|
+
("send_email_from_email_account_id", send_email_from_email_account_id),
|
|
1407
|
+
("sequence_no_email", sequence_no_email),
|
|
1408
|
+
("sequence_unverified_email", sequence_unverified_email),
|
|
1409
|
+
("sequence_job_change", sequence_job_change),
|
|
1410
|
+
(
|
|
1411
|
+
"sequence_active_in_other_campaigns",
|
|
1412
|
+
sequence_active_in_other_campaigns,
|
|
1413
|
+
),
|
|
1414
|
+
(
|
|
1415
|
+
"sequence_finished_in_other_campaigns",
|
|
1416
|
+
sequence_finished_in_other_campaigns,
|
|
1417
|
+
),
|
|
1418
|
+
("user_id", user_id),
|
|
1419
|
+
]
|
|
1420
|
+
if v is not None
|
|
1421
|
+
}
|
|
1422
|
+
response = self._post(
|
|
1423
|
+
url,
|
|
1424
|
+
data=request_body_data,
|
|
1425
|
+
params=query_params,
|
|
1426
|
+
content_type="application/json",
|
|
1427
|
+
)
|
|
1428
|
+
response.raise_for_status()
|
|
1429
|
+
if (
|
|
1430
|
+
response.status_code == 204
|
|
1431
|
+
or not response.content
|
|
1432
|
+
or not response.text.strip()
|
|
1433
|
+
):
|
|
1434
|
+
return None
|
|
1435
|
+
try:
|
|
1436
|
+
return response.json()
|
|
1437
|
+
except ValueError:
|
|
1438
|
+
return None
|
|
1439
|
+
|
|
1440
|
+
def update_contact_status_sequence(
|
|
1441
|
+
self, emailer_campaign_ids_: list[str], contact_ids_: list[str], mode: str
|
|
1442
|
+
) -> dict[str, Any]:
|
|
1443
|
+
"""
|
|
1444
|
+
Posts a request to remove or stop specified contact IDs from given emailer campaign IDs based on the selected mode.
|
|
1445
|
+
|
|
1446
|
+
Args:
|
|
1447
|
+
emailer_campaign_ids_ (array): The Apollo sequence IDs to update contact statuses in; providing multiple IDs updates contacts across all specified sequences. Use the Search for Sequences endpoint to find these IDs.
|
|
1448
|
+
contact_ids_ (array): Specify the Apollo IDs of contacts to update their sequence status. Obtain IDs via the Search for Contacts endpoint.
|
|
1449
|
+
mode (string): Choose one option to update contacts' sequence status: `mark_as_finished` to mark as completed, `remove` to delete from the sequence, or `stop` to pause their progression.
|
|
1450
|
+
|
|
1451
|
+
Returns:
|
|
1452
|
+
dict[str, Any]: 200
|
|
1453
|
+
|
|
1454
|
+
Raises:
|
|
1455
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1456
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1457
|
+
|
|
1458
|
+
Tags:
|
|
1459
|
+
Contacts
|
|
1460
|
+
"""
|
|
1461
|
+
request_body_data = None
|
|
1462
|
+
url = f"{self.base_url}/emailer_campaigns/remove_or_stop_contact_ids"
|
|
1463
|
+
query_params = {
|
|
1464
|
+
k: v
|
|
1465
|
+
for k, v in [
|
|
1466
|
+
("emailer_campaign_ids[]", emailer_campaign_ids_),
|
|
1467
|
+
("contact_ids[]", contact_ids_),
|
|
1468
|
+
("mode", mode),
|
|
1469
|
+
]
|
|
1470
|
+
if v is not None
|
|
1471
|
+
}
|
|
1472
|
+
response = self._post(
|
|
1473
|
+
url,
|
|
1474
|
+
data=request_body_data,
|
|
1475
|
+
params=query_params,
|
|
1476
|
+
content_type="application/json",
|
|
1477
|
+
)
|
|
1478
|
+
response.raise_for_status()
|
|
1479
|
+
if (
|
|
1480
|
+
response.status_code == 204
|
|
1481
|
+
or not response.content
|
|
1482
|
+
or not response.text.strip()
|
|
1483
|
+
):
|
|
1484
|
+
return None
|
|
1485
|
+
try:
|
|
1486
|
+
return response.json()
|
|
1487
|
+
except ValueError:
|
|
1488
|
+
return None
|
|
1489
|
+
|
|
1490
|
+
def create_task(
|
|
1491
|
+
self,
|
|
1492
|
+
user_id: str,
|
|
1493
|
+
contact_ids_: list[str],
|
|
1494
|
+
priority: str,
|
|
1495
|
+
due_at: str,
|
|
1496
|
+
type: str,
|
|
1497
|
+
status: str,
|
|
1498
|
+
note: str | None = None,
|
|
1499
|
+
) -> Any:
|
|
1500
|
+
"""
|
|
1501
|
+
Creates multiple tasks in bulk with specified user, contact IDs, priority, due date, type, status, and optional note parameters.
|
|
1502
|
+
|
|
1503
|
+
Args:
|
|
1504
|
+
user_id (string): The user_id query parameter specifies the unique identifier of the Apollo team member who will own and take action on the created tasks; retrieve user IDs from the Get a List of Users endpoint.
|
|
1505
|
+
contact_ids_ (array): Apollo IDs of contacts to receive the action; multiple IDs create separate tasks with the same details.
|
|
1506
|
+
priority (string): Specify the priority level for each task being created in bulk; valid values are "high," "medium," or "low" to indicate urgency.
|
|
1507
|
+
due_at (string): The full date and time when the task is due, in ISO 8601 format. Use GMT by default or specify a time zone offset (e.g., `2025-02-15T08:10:30Z`, `2025-03-25T10:15:30+05:00`).
|
|
1508
|
+
type (string): Specify the task type to clarify the action required: `call` to call contacts, `outreach_manual_email` to email, `linkedin_step_connect` to send connection invites, `linkedin_step_message` to message on LinkedIn, `linkedin_step_view_profile` to view
|
|
1509
|
+
status (string): The status of the task being created. Use `scheduled` for future tasks, `completed` for finished tasks, or `archived` for completed tasks no longer needed.
|
|
1510
|
+
note (string): Optional task note: human-readable description to give context for the action required. Example: "Contact interested in Sequences; discuss details."
|
|
1511
|
+
|
|
1512
|
+
Returns:
|
|
1513
|
+
Any: 200
|
|
1514
|
+
|
|
1515
|
+
Raises:
|
|
1516
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1517
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1518
|
+
|
|
1519
|
+
Tags:
|
|
1520
|
+
Tasks
|
|
1521
|
+
"""
|
|
1522
|
+
request_body_data = None
|
|
1523
|
+
url = f"{self.base_url}/tasks/bulk_create"
|
|
1524
|
+
query_params = {
|
|
1525
|
+
k: v
|
|
1526
|
+
for k, v in [
|
|
1527
|
+
("user_id", user_id),
|
|
1528
|
+
("contact_ids[]", contact_ids_),
|
|
1529
|
+
("priority", priority),
|
|
1530
|
+
("due_at", due_at),
|
|
1531
|
+
("type", type),
|
|
1532
|
+
("status", status),
|
|
1533
|
+
("note", note),
|
|
1534
|
+
]
|
|
1535
|
+
if v is not None
|
|
1536
|
+
}
|
|
1537
|
+
response = self._post(
|
|
1538
|
+
url,
|
|
1539
|
+
data=request_body_data,
|
|
1540
|
+
params=query_params,
|
|
1541
|
+
content_type="application/json",
|
|
1542
|
+
)
|
|
1543
|
+
response.raise_for_status()
|
|
1544
|
+
if (
|
|
1545
|
+
response.status_code == 204
|
|
1546
|
+
or not response.content
|
|
1547
|
+
or not response.text.strip()
|
|
1548
|
+
):
|
|
1549
|
+
return None
|
|
1550
|
+
try:
|
|
1551
|
+
return response.json()
|
|
1552
|
+
except ValueError:
|
|
1553
|
+
return None
|
|
1554
|
+
|
|
1555
|
+
def search_tasks(
|
|
1556
|
+
self,
|
|
1557
|
+
sort_by_field: str | None = None,
|
|
1558
|
+
open_factor_names_: list[str] | None = None,
|
|
1559
|
+
page: int | None = None,
|
|
1560
|
+
per_page: int | None = None,
|
|
1561
|
+
) -> dict[str, Any]:
|
|
1562
|
+
"""
|
|
1563
|
+
Searches for tasks using specified parameters and returns a paginated list of results, allowing users to sort by a field and filter by open factor names.
|
|
1564
|
+
|
|
1565
|
+
Args:
|
|
1566
|
+
sort_by_field (string): Specify field to sort tasks: 'task_due_at' (most future first) or 'task_priority' (highest first).
|
|
1567
|
+
open_factor_names_ (array): Enter `task_types` to receive a count of tasks grouped by each task type; the response will include a `task_types` array with counts for each type.
|
|
1568
|
+
page (integer): The page query parameter specifies which page of Apollo data to retrieve, used with per_page to paginate results and optimize search performance; for example, 4.
|
|
1569
|
+
per_page (integer): The number of search results returned per page to improve response performance; use the `page` parameter to access additional pages. Example: `10`.
|
|
1570
|
+
|
|
1571
|
+
Returns:
|
|
1572
|
+
dict[str, Any]: 200
|
|
1573
|
+
|
|
1574
|
+
Raises:
|
|
1575
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1576
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1577
|
+
|
|
1578
|
+
Tags:
|
|
1579
|
+
Tasks
|
|
1580
|
+
"""
|
|
1581
|
+
request_body_data = None
|
|
1582
|
+
url = f"{self.base_url}/tasks/search"
|
|
1583
|
+
query_params = {
|
|
1584
|
+
k: v
|
|
1585
|
+
for k, v in [
|
|
1586
|
+
("sort_by_field", sort_by_field),
|
|
1587
|
+
("open_factor_names[]", open_factor_names_),
|
|
1588
|
+
("page", page),
|
|
1589
|
+
("per_page", per_page),
|
|
1590
|
+
]
|
|
1591
|
+
if v is not None
|
|
1592
|
+
}
|
|
1593
|
+
response = self._post(
|
|
1594
|
+
url,
|
|
1595
|
+
data=request_body_data,
|
|
1596
|
+
params=query_params,
|
|
1597
|
+
content_type="application/json",
|
|
1598
|
+
)
|
|
1599
|
+
response.raise_for_status()
|
|
1600
|
+
if (
|
|
1601
|
+
response.status_code == 204
|
|
1602
|
+
or not response.content
|
|
1603
|
+
or not response.text.strip()
|
|
1604
|
+
):
|
|
1605
|
+
return None
|
|
1606
|
+
try:
|
|
1607
|
+
return response.json()
|
|
1608
|
+
except ValueError:
|
|
1609
|
+
return None
|
|
1610
|
+
|
|
1611
|
+
def get_a_list_of_users(
|
|
1612
|
+
self, page: int | None = None, per_page: int | None = None
|
|
1613
|
+
) -> dict[str, Any]:
|
|
1614
|
+
"""
|
|
1615
|
+
Searches for users with optional pagination parameters to specify the page number and number of results per page.
|
|
1616
|
+
|
|
1617
|
+
Args:
|
|
1618
|
+
page (integer): The page number of results to retrieve in the search, used with `per_page` to paginate and improve response performance; for example, `4`.
|
|
1619
|
+
per_page (integer): The number of search results returned per page to control response size and improve performance; use the `page` parameter to access additional pages. Example: 10.
|
|
1620
|
+
|
|
1621
|
+
Returns:
|
|
1622
|
+
dict[str, Any]: 200
|
|
1623
|
+
|
|
1624
|
+
Raises:
|
|
1625
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1626
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1627
|
+
|
|
1628
|
+
Tags:
|
|
1629
|
+
Users
|
|
1630
|
+
"""
|
|
1631
|
+
url = f"{self.base_url}/users/search"
|
|
1632
|
+
query_params = {
|
|
1633
|
+
k: v for k, v in [("page", page), ("per_page", per_page)] if v is not None
|
|
1634
|
+
}
|
|
1635
|
+
response = self._get(url, params=query_params)
|
|
1636
|
+
response.raise_for_status()
|
|
1637
|
+
if (
|
|
1638
|
+
response.status_code == 204
|
|
1639
|
+
or not response.content
|
|
1640
|
+
or not response.text.strip()
|
|
1641
|
+
):
|
|
1642
|
+
return None
|
|
1643
|
+
try:
|
|
1644
|
+
return response.json()
|
|
1645
|
+
except ValueError:
|
|
1646
|
+
return None
|
|
1647
|
+
|
|
1648
|
+
def get_a_list_of_email_accounts(self) -> dict[str, Any]:
|
|
1649
|
+
"""
|
|
1650
|
+
Retrieves a list of all available email accounts and their summary information.
|
|
1651
|
+
|
|
1652
|
+
Returns:
|
|
1653
|
+
dict[str, Any]: 200
|
|
1654
|
+
|
|
1655
|
+
Raises:
|
|
1656
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1657
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1658
|
+
|
|
1659
|
+
Tags:
|
|
1660
|
+
Email Accounts
|
|
1661
|
+
"""
|
|
1662
|
+
url = f"{self.base_url}/email_accounts"
|
|
1663
|
+
query_params = {}
|
|
1664
|
+
response = self._get(url, params=query_params)
|
|
1665
|
+
response.raise_for_status()
|
|
1666
|
+
if (
|
|
1667
|
+
response.status_code == 204
|
|
1668
|
+
or not response.content
|
|
1669
|
+
or not response.text.strip()
|
|
1670
|
+
):
|
|
1671
|
+
return None
|
|
1672
|
+
try:
|
|
1673
|
+
return response.json()
|
|
1674
|
+
except ValueError:
|
|
1675
|
+
return None
|
|
1676
|
+
|
|
1677
|
+
def get_a_list_of_all_liststags(self) -> list[Any]:
|
|
1678
|
+
"""
|
|
1679
|
+
Retrieves a list of labels.
|
|
1680
|
+
|
|
1681
|
+
Returns:
|
|
1682
|
+
list[Any]: 200
|
|
1683
|
+
|
|
1684
|
+
Raises:
|
|
1685
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1686
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1687
|
+
|
|
1688
|
+
Tags:
|
|
1689
|
+
Labels
|
|
1690
|
+
"""
|
|
1691
|
+
url = f"{self.base_url}/labels"
|
|
1692
|
+
query_params = {}
|
|
1693
|
+
response = self._get(url, params=query_params)
|
|
1694
|
+
response.raise_for_status()
|
|
1695
|
+
if (
|
|
1696
|
+
response.status_code == 204
|
|
1697
|
+
or not response.content
|
|
1698
|
+
or not response.text.strip()
|
|
1699
|
+
):
|
|
1700
|
+
return None
|
|
1701
|
+
try:
|
|
1702
|
+
return response.json()
|
|
1703
|
+
except ValueError:
|
|
1704
|
+
return None
|
|
1705
|
+
|
|
1706
|
+
def get_a_list_of_all_custom_fields(self) -> dict[str, Any]:
|
|
1707
|
+
"""
|
|
1708
|
+
Retrieves a list of all typed custom fields configured in the system.
|
|
1709
|
+
|
|
1710
|
+
Returns:
|
|
1711
|
+
dict[str, Any]: 200
|
|
1712
|
+
|
|
1713
|
+
Raises:
|
|
1714
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1715
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1716
|
+
|
|
1717
|
+
Tags:
|
|
1718
|
+
Custom Fields
|
|
1719
|
+
"""
|
|
1720
|
+
url = f"{self.base_url}/typed_custom_fields"
|
|
1721
|
+
query_params = {}
|
|
1722
|
+
response = self._get(url, params=query_params)
|
|
1723
|
+
response.raise_for_status()
|
|
1724
|
+
if (
|
|
1725
|
+
response.status_code == 204
|
|
1726
|
+
or not response.content
|
|
1727
|
+
or not response.text.strip()
|
|
1728
|
+
):
|
|
1729
|
+
return None
|
|
1730
|
+
try:
|
|
1731
|
+
return response.json()
|
|
1732
|
+
except ValueError:
|
|
1733
|
+
return None
|
|
1734
|
+
|
|
1735
|
+
def view_deal(self, opportunity_id: str) -> dict[str, Any]:
|
|
1736
|
+
"""
|
|
1737
|
+
View Deal by opportunity_id
|
|
1738
|
+
|
|
1739
|
+
Args:
|
|
1740
|
+
opportunity_id (string): opportunity_id
|
|
1741
|
+
|
|
1742
|
+
Returns:
|
|
1743
|
+
dict[str, Any]: 200
|
|
1744
|
+
|
|
1745
|
+
Raises:
|
|
1746
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1747
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1748
|
+
"""
|
|
1749
|
+
if opportunity_id is None:
|
|
1750
|
+
raise ValueError("Missing required parameter 'opportunity_id'.")
|
|
1751
|
+
url = f"{self.base_url}/opportunities/{opportunity_id}"
|
|
1752
|
+
query_params = {}
|
|
1753
|
+
response = self._get(url, params=query_params)
|
|
1754
|
+
response.raise_for_status()
|
|
1755
|
+
if (
|
|
1756
|
+
response.status_code == 204
|
|
1757
|
+
or not response.content
|
|
1758
|
+
or not response.text.strip()
|
|
1759
|
+
):
|
|
1760
|
+
return None
|
|
1761
|
+
try:
|
|
1762
|
+
return response.json()
|
|
1763
|
+
except ValueError:
|
|
1764
|
+
return None
|
|
1765
|
+
|
|
1766
|
+
def search_for_sequences(
|
|
1767
|
+
self,
|
|
1768
|
+
q_name: str | None = None,
|
|
1769
|
+
page: str | None = None,
|
|
1770
|
+
per_page: str | None = None,
|
|
1771
|
+
) -> dict[str, Any]:
|
|
1772
|
+
"""
|
|
1773
|
+
Search for Sequences by name
|
|
1774
|
+
|
|
1775
|
+
Args:
|
|
1776
|
+
q_name (string): Add keywords to narrow the search of the sequences in your team's Apollo account. <br><br>Keywords should directly match at least part of a sequence's name. For example, searching the keyword `marketing` might return the result `NY Marketing Sequence`, but not `NY Marketer Conference 2025 attendees`. <br><br>This parameter only searches sequence names, not other sequence fields. <br><br>Example: `marketing conference attendees`
|
|
1777
|
+
page (string): The page number of the Apollo data that you want to retrieve. <br><br>Use this parameter in combination with the `per_page` parameter to make search results for navigable and improve the performance of the endpoint. <br><br>Example: `4`
|
|
1778
|
+
per_page (string): The number of search results that should be returned for each page. Limited the number of results per page improves the endpoint's performance. <br><br>Use the `page` parameter to search the different pages of data. <br><br>Example: `10`
|
|
1779
|
+
|
|
1780
|
+
Returns:
|
|
1781
|
+
dict[str, Any]: 200
|
|
1782
|
+
|
|
1783
|
+
Raises:
|
|
1784
|
+
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
1785
|
+
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
1786
|
+
"""
|
|
1787
|
+
request_body_data = None
|
|
1788
|
+
url = f"{self.base_url}/emailer_campaigns/search"
|
|
1789
|
+
query_params = {
|
|
1790
|
+
k: v
|
|
1791
|
+
for k, v in [("q_name", q_name), ("page", page), ("per_page", per_page)]
|
|
1792
|
+
if v is not None
|
|
1793
|
+
}
|
|
1794
|
+
response = self._post(
|
|
1795
|
+
url,
|
|
1796
|
+
data=request_body_data,
|
|
1797
|
+
params=query_params,
|
|
1798
|
+
content_type="application/json",
|
|
1799
|
+
)
|
|
1800
|
+
response.raise_for_status()
|
|
1801
|
+
if (
|
|
1802
|
+
response.status_code == 204
|
|
1803
|
+
or not response.content
|
|
1804
|
+
or not response.text.strip()
|
|
1805
|
+
):
|
|
1806
|
+
return None
|
|
1807
|
+
try:
|
|
1808
|
+
return response.json()
|
|
1809
|
+
except ValueError:
|
|
1810
|
+
return None
|
|
1811
|
+
|
|
1812
|
+
def list_tools(self):
|
|
1813
|
+
return [
|
|
1814
|
+
self.people_enrichment,
|
|
1815
|
+
self.bulk_people_enrichment,
|
|
1816
|
+
self.organization_enrichment,
|
|
1817
|
+
self.bulk_organization_enrichment,
|
|
1818
|
+
self.people_search,
|
|
1819
|
+
self.organization_search,
|
|
1820
|
+
self.organization_jobs_postings,
|
|
1821
|
+
self.create_an_account,
|
|
1822
|
+
self.update_an_account,
|
|
1823
|
+
self.search_for_accounts,
|
|
1824
|
+
self.update_account_stage,
|
|
1825
|
+
self.update_account_ownership,
|
|
1826
|
+
self.list_account_stages,
|
|
1827
|
+
self.create_a_contact,
|
|
1828
|
+
self.update_a_contact,
|
|
1829
|
+
self.search_for_contacts,
|
|
1830
|
+
self.update_contact_stage,
|
|
1831
|
+
self.update_contact_ownership,
|
|
1832
|
+
self.list_contact_stages,
|
|
1833
|
+
self.create_deal,
|
|
1834
|
+
self.list_all_deals,
|
|
1835
|
+
self.update_deal,
|
|
1836
|
+
self.list_deal_stages,
|
|
1837
|
+
self.add_contacts_to_sequence,
|
|
1838
|
+
self.update_contact_status_sequence,
|
|
1839
|
+
self.create_task,
|
|
1840
|
+
self.search_tasks,
|
|
1841
|
+
self.get_a_list_of_users,
|
|
1842
|
+
self.get_a_list_of_email_accounts,
|
|
1843
|
+
self.get_a_list_of_all_liststags,
|
|
1844
|
+
self.get_a_list_of_all_custom_fields,
|
|
1845
|
+
self.view_deal,
|
|
1846
|
+
self.search_for_sequences,
|
|
1847
|
+
]
|