orangeslice 2.1.5 → 2.4.0-beta.0
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.
- package/README.md +20 -1
- package/dist/careers.d.ts +47 -0
- package/dist/careers.js +11 -0
- package/dist/cli.js +12 -1
- package/dist/index.d.ts +41 -0
- package/dist/index.js +29 -3
- package/dist/integrations.d.ts +60 -0
- package/dist/integrations.js +107 -0
- package/dist/ocean.d.ts +160 -0
- package/dist/ocean.js +23 -0
- package/dist/skills.d.ts +57 -0
- package/dist/skills.js +33 -0
- package/docs/data-enrichement/index.md +10 -2
- package/docs/integrations/gmail/createDraft.md +54 -0
- package/docs/integrations/gmail/fetchEmails.md +50 -0
- package/docs/integrations/gmail/fetchMessageByMessageId.md +36 -0
- package/docs/integrations/gmail/fetchMessageByThreadId.md +37 -0
- package/docs/integrations/gmail/getProfile.md +37 -0
- package/docs/integrations/gmail/index.md +19 -2
- package/docs/integrations/gmail/listLabels.md +34 -0
- package/docs/integrations/gmail/replyToThread.md +51 -0
- package/docs/integrations/index.md +14 -1
- package/docs/lookalike-search/index.md +24 -12
- package/docs/prospecting/index.md +2 -2
- package/docs/services/builtWith/index.md +2 -2
- package/docs/services/company/findCareersPage.md +137 -0
- package/docs/services/company/findCareersPage.ts +37 -0
- package/docs/services/company/linkedin/enrich.md +47 -1
- package/docs/services/company/scrapeCareersPage.md +150 -0
- package/docs/services/index.md +4 -2
- package/docs/services/integrations/index.md +128 -0
- package/docs/services/ocean/search/companies.ts +122 -119
- package/docs/services/person/linkedin/findUrl.md +2 -2
- package/docs/services/predictLeads/companyJobOpenings.ts +168 -94
- package/docs/services/skills/index.md +97 -0
- package/docs/services/web/search.md +29 -14
- package/package.json +1 -1
package/dist/skills.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Skills API for the orangeslice SDK.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { skills } from "orangeslice";
|
|
6
|
+
*
|
|
7
|
+
* // Create a skill
|
|
8
|
+
* const skill = await skills.create({
|
|
9
|
+
* title: "CRM Mapping",
|
|
10
|
+
* description: "Maps company fields to HubSpot properties",
|
|
11
|
+
* content: "When pushing to HubSpot, map ...",
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* // List all skills
|
|
15
|
+
* const { skills: list } = await skills.list();
|
|
16
|
+
*
|
|
17
|
+
* // Update a skill
|
|
18
|
+
* await skills.update(skill.id, { autoInject: true });
|
|
19
|
+
*/
|
|
20
|
+
export interface Skill {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
description: string;
|
|
24
|
+
content: string;
|
|
25
|
+
autoInject: boolean;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
updatedAt: string;
|
|
28
|
+
scope: "account" | "spreadsheet";
|
|
29
|
+
spreadsheetId?: string | null;
|
|
30
|
+
}
|
|
31
|
+
export interface SkillListParams {
|
|
32
|
+
spreadsheetId?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface SkillCreateParams {
|
|
35
|
+
title: string;
|
|
36
|
+
description: string;
|
|
37
|
+
content: string;
|
|
38
|
+
autoInject?: boolean;
|
|
39
|
+
spreadsheetId?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface SkillUpdateParams {
|
|
42
|
+
title?: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
content?: string;
|
|
45
|
+
autoInject?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare const skills: {
|
|
48
|
+
list: (opts?: SkillListParams) => Promise<{
|
|
49
|
+
skills: Skill[];
|
|
50
|
+
}>;
|
|
51
|
+
get: (id: string) => Promise<Skill>;
|
|
52
|
+
create: (opts: SkillCreateParams) => Promise<Skill>;
|
|
53
|
+
update: (id: string, fields: SkillUpdateParams) => Promise<Skill>;
|
|
54
|
+
delete: (id: string) => Promise<{
|
|
55
|
+
success: boolean;
|
|
56
|
+
}>;
|
|
57
|
+
};
|
package/dist/skills.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Knowledge Skills API for the orangeslice SDK.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* import { skills } from "orangeslice";
|
|
7
|
+
*
|
|
8
|
+
* // Create a skill
|
|
9
|
+
* const skill = await skills.create({
|
|
10
|
+
* title: "CRM Mapping",
|
|
11
|
+
* description: "Maps company fields to HubSpot properties",
|
|
12
|
+
* content: "When pushing to HubSpot, map ...",
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* // List all skills
|
|
16
|
+
* const { skills: list } = await skills.list();
|
|
17
|
+
*
|
|
18
|
+
* // Update a skill
|
|
19
|
+
* await skills.update(skill.id, { autoInject: true });
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.skills = void 0;
|
|
23
|
+
const api_1 = require("./api");
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// CRUD (via batch-service)
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
exports.skills = {
|
|
28
|
+
list: (opts) => (0, api_1.post)("/ctx/skills/list", (opts ?? {})),
|
|
29
|
+
get: (id) => (0, api_1.post)("/ctx/skills/get", { id }),
|
|
30
|
+
create: (opts) => (0, api_1.post)("/ctx/skills/create", opts),
|
|
31
|
+
update: (id, fields) => (0, api_1.post)("/ctx/skills/update", { id, ...fields }),
|
|
32
|
+
delete: (id) => (0, api_1.post)("/ctx/skills/delete", { id })
|
|
33
|
+
};
|
|
@@ -5,12 +5,18 @@ description: Patterns for enriching company data, tech stack detection, hiring d
|
|
|
5
5
|
|
|
6
6
|
# Data Enrichment
|
|
7
7
|
|
|
8
|
-
Standard pattern: **Search → Scrape → Extract**
|
|
8
|
+
Standard pattern: **Search/Domain → Scrape → Extract**
|
|
9
9
|
|
|
10
|
-
1. `web.search` with `site:` to find
|
|
10
|
+
1. Start with a company `domain` when you already have it, otherwise use `web.search` with `site:` to find relevant pages
|
|
11
11
|
2. `scrape.website` to get page content as markdown
|
|
12
12
|
3. `ai.generateObject` to extract structured fields
|
|
13
13
|
|
|
14
|
+
For company enrichment/classification, prefer the website over LinkedIn `industry`.
|
|
15
|
+
|
|
16
|
+
- LinkedIn `industry` is acceptable as lightweight lookup context
|
|
17
|
+
- LinkedIn `industry` is too sparse/generic to be your main enrichment signal
|
|
18
|
+
- Preferred workflow: `domain` -> `scrape.website` -> `ai.generateObject`
|
|
19
|
+
|
|
14
20
|
---
|
|
15
21
|
|
|
16
22
|
## Example: Does this law firm handle medical malpractice?
|
|
@@ -42,6 +48,8 @@ async function checkMedMalPractice(domain: string) {
|
|
|
42
48
|
|
|
43
49
|
---
|
|
44
50
|
|
|
51
|
+
---
|
|
52
|
+
|
|
45
53
|
## When to Use
|
|
46
54
|
|
|
47
55
|
| Use Search → Scrape → Extract | Use `browser.execute` instead |
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# createDraft
|
|
2
|
+
|
|
3
|
+
Create a Gmail draft without sending it yet.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// Create a new draft
|
|
7
|
+
const draft = await integrations.gmail.createDraft({
|
|
8
|
+
recipient_email: "jane@example.com",
|
|
9
|
+
subject: "Draft follow-up",
|
|
10
|
+
body: "Sharing a quick follow-up before I send this."
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Draft a reply in an existing thread
|
|
14
|
+
await integrations.gmail.createDraft({
|
|
15
|
+
thread_id: "19bf77729bcb3a44",
|
|
16
|
+
body: "Thanks for the update. I will review this today."
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Input
|
|
21
|
+
|
|
22
|
+
| Parameter | Type | Required | Description |
|
|
23
|
+
| ------------------ | ---------- | -------- | -------------------------------------------- |
|
|
24
|
+
| `recipient_email` | `string` | No | Primary `To` recipient |
|
|
25
|
+
| `extra_recipients` | `string[]` | No | Additional `To` recipients |
|
|
26
|
+
| `cc` | `string[]` | No | CC recipients |
|
|
27
|
+
| `bcc` | `string[]` | No | BCC recipients |
|
|
28
|
+
| `subject` | `string` | No | Draft subject |
|
|
29
|
+
| `body` | `string` | No | Draft body content |
|
|
30
|
+
| `message_body` | `string` | No | Alternate body field accepted by some tools |
|
|
31
|
+
| `is_html` | `boolean` | No | Set to `true` when `body` contains HTML |
|
|
32
|
+
| `attachment` | `object` | No | Optional attachment payload |
|
|
33
|
+
| `thread_id` | `string` | No | Existing thread to draft a reply into |
|
|
34
|
+
| `from_email` | `string` | No | Optional verified send-as alias |
|
|
35
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
36
|
+
|
|
37
|
+
## Output
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
{
|
|
41
|
+
successful: boolean;
|
|
42
|
+
data?: {
|
|
43
|
+
id?: string;
|
|
44
|
+
draft_id?: string;
|
|
45
|
+
message?: GmailMessage;
|
|
46
|
+
};
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Notes
|
|
52
|
+
|
|
53
|
+
- Creating a draft is a mutating action and should be used intentionally
|
|
54
|
+
- If you pass `thread_id`, leave `subject` empty to stay in the existing thread
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# fetchEmails
|
|
2
|
+
|
|
3
|
+
Fetch inbox messages or Gmail search results from the connected account.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// Read the current inbox
|
|
7
|
+
const inbox = await integrations.gmail.fetchEmails({
|
|
8
|
+
query: "in:inbox",
|
|
9
|
+
max_results: 10
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
// Search for unread emails from a sender
|
|
13
|
+
const unread = await integrations.gmail.fetchEmails({
|
|
14
|
+
query: "in:inbox is:unread from:alice@example.com",
|
|
15
|
+
max_results: 25
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Input
|
|
20
|
+
|
|
21
|
+
| Parameter | Type | Required | Description |
|
|
22
|
+
| --------------------- | ---------- | -------- | ----------------------------------------------------- |
|
|
23
|
+
| `query` | `string` | No | Gmail search query such as `in:inbox is:unread` |
|
|
24
|
+
| `verbose` | `boolean` | No | Fetch richer message details |
|
|
25
|
+
| `ids_only` | `boolean` | No | Only return message/thread identifiers |
|
|
26
|
+
| `label_ids` | `string[]` | No | Filter by Gmail label IDs |
|
|
27
|
+
| `page_token` | `string` | No | Pagination token from a previous call |
|
|
28
|
+
| `max_results` | `number` | No | Maximum messages to fetch in this page |
|
|
29
|
+
| `include_payload` | `boolean` | No | Include payload/body data when available |
|
|
30
|
+
| `include_spam_trash` | `boolean` | No | Include spam and trash |
|
|
31
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
32
|
+
|
|
33
|
+
## Output
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
{
|
|
37
|
+
successful: boolean;
|
|
38
|
+
data?: {
|
|
39
|
+
messages?: GmailMessage[];
|
|
40
|
+
nextPageToken?: string;
|
|
41
|
+
resultSizeEstimate?: number;
|
|
42
|
+
};
|
|
43
|
+
error?: string;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Notes
|
|
48
|
+
|
|
49
|
+
- Results are not guaranteed to be sorted by recency, so sort client-side if order matters
|
|
50
|
+
- For large mailboxes, fetch IDs first and then hydrate specific messages with `fetchMessageByMessageId(...)`
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# fetchMessageByMessageId
|
|
2
|
+
|
|
3
|
+
Fetch a single Gmail message by its Gmail API message ID.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const message = await integrations.gmail.fetchMessageByMessageId({
|
|
7
|
+
message_id: "19b11732c1b578fd",
|
|
8
|
+
format: "full"
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
console.log(message.data?.subject);
|
|
12
|
+
console.log(message.data?.threadId);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Input
|
|
16
|
+
|
|
17
|
+
| Parameter | Type | Required | Description |
|
|
18
|
+
| ------------- | ----------------------------------------- | -------- | -------------------------------------- |
|
|
19
|
+
| `message_id` | `string` | Yes | Gmail API message ID |
|
|
20
|
+
| `format` | `\"minimal\" | \"full\" | \"raw\" | \"metadata\"` | No | Response format |
|
|
21
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
22
|
+
|
|
23
|
+
## Output
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
{
|
|
27
|
+
successful: boolean;
|
|
28
|
+
data?: GmailMessage;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Notes
|
|
34
|
+
|
|
35
|
+
- Use real Gmail `message_id` values returned by Gmail list/search actions
|
|
36
|
+
- `format: "full"` is best when you need headers, payload parts, or body data
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# fetchMessageByThreadId
|
|
2
|
+
|
|
3
|
+
Fetch all messages belonging to a Gmail thread.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const thread = await integrations.gmail.fetchMessageByThreadId({
|
|
7
|
+
thread_id: "19bf77729bcb3a44"
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
for (const message of thread.data?.messages || []) {
|
|
11
|
+
console.log(message.subject);
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Input
|
|
16
|
+
|
|
17
|
+
| Parameter | Type | Required | Description |
|
|
18
|
+
| ------------ | -------- | -------- | ----------------------------------- |
|
|
19
|
+
| `thread_id` | `string` | Yes | Gmail API thread ID |
|
|
20
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
21
|
+
|
|
22
|
+
## Output
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
{
|
|
26
|
+
successful: boolean;
|
|
27
|
+
data?: {
|
|
28
|
+
messages?: GmailMessage[];
|
|
29
|
+
};
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Notes
|
|
35
|
+
|
|
36
|
+
- Message order is not guaranteed, so sort by `internalDate` if you need oldest/newest order
|
|
37
|
+
- Read threads first before calling `replyToThread(...)` so you have the correct `thread_id`
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# getProfile
|
|
2
|
+
|
|
3
|
+
Read Gmail profile metadata for the connected account.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const profile = await integrations.gmail.getProfile();
|
|
7
|
+
|
|
8
|
+
console.log(profile.data?.emailAddress);
|
|
9
|
+
console.log(profile.data?.messagesTotal);
|
|
10
|
+
console.log(profile.data?.threadsTotal);
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
| Parameter | Type | Required | Description |
|
|
16
|
+
| --------- | -------- | -------- | ----------------------------------- |
|
|
17
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
18
|
+
|
|
19
|
+
## Output
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
{
|
|
23
|
+
successful: boolean;
|
|
24
|
+
data?: {
|
|
25
|
+
emailAddress?: string;
|
|
26
|
+
messagesTotal?: number;
|
|
27
|
+
threadsTotal?: number;
|
|
28
|
+
historyId?: string;
|
|
29
|
+
};
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Notes
|
|
35
|
+
|
|
36
|
+
- This is a lightweight way to confirm which mailbox is connected
|
|
37
|
+
- Mailbox totals are useful for diagnostics, health checks, and quick account introspection
|
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Gmail email sending via Google integration
|
|
2
|
+
description: Gmail inbox, drafts, threads, labels, profile, and email sending via Google integration
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Gmail Integration
|
|
6
6
|
|
|
7
7
|
Typed functions for Gmail actions powered by Orange Slice Google integrations.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Write Actions
|
|
10
10
|
|
|
11
11
|
- `integrations.gmail.sendEmail(input)` - Send an email through the connected Gmail account
|
|
12
|
+
- `integrations.gmail.createDraft(input)` - Create a Gmail draft without sending it
|
|
13
|
+
- `integrations.gmail.replyToThread(input)` - Reply inside an existing Gmail thread
|
|
12
14
|
- Heavy rate limit: `sendEmail` is capped at **40 calls/day** per connected Gmail account
|
|
15
|
+
- Mutating Gmail actions should be used intentionally because they require approval
|
|
16
|
+
|
|
17
|
+
## Read Actions
|
|
18
|
+
|
|
19
|
+
- `integrations.gmail.fetchEmails(input)` - Read inbox messages or Gmail search results
|
|
20
|
+
- `integrations.gmail.fetchMessageByMessageId(input)` - Fetch one message by Gmail message ID
|
|
21
|
+
- `integrations.gmail.fetchMessageByThreadId(input)` - Fetch all messages in a Gmail thread
|
|
22
|
+
- `integrations.gmail.listLabels(input)` - List Gmail system and custom labels
|
|
23
|
+
- `integrations.gmail.getProfile(input)` - Read Gmail profile metadata such as mailbox counts
|
|
24
|
+
|
|
25
|
+
## Notes
|
|
26
|
+
|
|
27
|
+
- Prefer `fetchEmails({ query: "in:inbox", max_results: 10 })` to read the current inbox
|
|
28
|
+
- For large inbox scans, start with smaller `max_results` values or `ids_only: true`
|
|
29
|
+
- Use real `messageId` and `threadId` values returned by Gmail read methods before drilling into a message or thread
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# listLabels
|
|
2
|
+
|
|
3
|
+
List Gmail system labels and custom labels.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const labels = await integrations.gmail.listLabels();
|
|
7
|
+
|
|
8
|
+
for (const label of labels.data?.labels || []) {
|
|
9
|
+
console.log(label.id, label.name);
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
| Parameter | Type | Required | Description |
|
|
16
|
+
| --------- | -------- | -------- | ----------------------------------- |
|
|
17
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
18
|
+
|
|
19
|
+
## Output
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
{
|
|
23
|
+
successful: boolean;
|
|
24
|
+
data?: {
|
|
25
|
+
labels?: GmailLabel[];
|
|
26
|
+
};
|
|
27
|
+
error?: string;
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Notes
|
|
32
|
+
|
|
33
|
+
- Use this before any label-based workflow so you work with Gmail label IDs rather than display names
|
|
34
|
+
- System labels and custom labels can both appear in the response
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# replyToThread
|
|
2
|
+
|
|
3
|
+
Reply inside an existing Gmail thread.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
await integrations.gmail.replyToThread({
|
|
7
|
+
thread_id: "19bf77729bcb3a44",
|
|
8
|
+
body: "Thanks for the note. I will get back to you tomorrow."
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
await integrations.gmail.replyToThread({
|
|
12
|
+
thread_id: "19bf77729bcb3a44",
|
|
13
|
+
body: "<p>Reviewed and approved.</p>",
|
|
14
|
+
is_html: true
|
|
15
|
+
});
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Input
|
|
19
|
+
|
|
20
|
+
| Parameter | Type | Required | Description |
|
|
21
|
+
| ------------------ | ---------- | -------- | -------------------------------------------- |
|
|
22
|
+
| `thread_id` | `string` | Yes | Gmail thread to reply within |
|
|
23
|
+
| `body` | `string` | No | Reply body |
|
|
24
|
+
| `message_body` | `string` | No | Alternate body field accepted by some tools |
|
|
25
|
+
| `subject` | `string` | No | Optional subject override |
|
|
26
|
+
| `cc` | `string[]` | No | CC recipients |
|
|
27
|
+
| `bcc` | `string[]` | No | BCC recipients |
|
|
28
|
+
| `attachment` | `object` | No | Optional attachment payload |
|
|
29
|
+
| `is_html` | `boolean` | No | Set to `true` when `body` contains HTML |
|
|
30
|
+
| `from_email` | `string` | No | Optional verified send-as alias |
|
|
31
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
32
|
+
|
|
33
|
+
## Output
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
{
|
|
37
|
+
successful: boolean;
|
|
38
|
+
data?: {
|
|
39
|
+
id?: string;
|
|
40
|
+
messageId?: string;
|
|
41
|
+
threadId?: string;
|
|
42
|
+
labelIds?: string[];
|
|
43
|
+
};
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Notes
|
|
49
|
+
|
|
50
|
+
- This is a mutating action and should be used intentionally
|
|
51
|
+
- Use a real `thread_id` from `fetchEmails(...)` or `fetchMessageByThreadId(...)`
|
|
@@ -242,7 +242,7 @@ See [attio/](./attio/) for all available functions.
|
|
|
242
242
|
|
|
243
243
|
### Gmail
|
|
244
244
|
|
|
245
|
-
|
|
245
|
+
Read and write emails from connected Google Gmail accounts.
|
|
246
246
|
|
|
247
247
|
```typescript
|
|
248
248
|
// Send a plain text email
|
|
@@ -260,6 +260,19 @@ await integrations.gmail.sendEmail({
|
|
|
260
260
|
body: "<h2>Weekly Summary</h2><p>All systems operational.</p>",
|
|
261
261
|
is_html: true
|
|
262
262
|
});
|
|
263
|
+
|
|
264
|
+
// Read the current inbox
|
|
265
|
+
const inbox = await integrations.gmail.fetchEmails({
|
|
266
|
+
query: "in:inbox",
|
|
267
|
+
max_results: 10
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Create a draft without sending it
|
|
271
|
+
await integrations.gmail.createDraft({
|
|
272
|
+
recipient_email: "john@example.com",
|
|
273
|
+
subject: "Draft follow-up",
|
|
274
|
+
body: "This is saved as a draft."
|
|
275
|
+
});
|
|
263
276
|
```
|
|
264
277
|
|
|
265
278
|
See [gmail/](./gmail/) for available functions.
|
|
@@ -51,20 +51,32 @@ const results = await services.ocean.search.companies({
|
|
|
51
51
|
|
|
52
52
|
**Key filters:**
|
|
53
53
|
|
|
54
|
-
| Filter | Example
|
|
55
|
-
| ------------------ |
|
|
56
|
-
| `lookalikeDomains` | `["stripe.com", "plaid.com"]`
|
|
57
|
-
| `companySizes` | `["51-200", "201-500"]`
|
|
58
|
-
| `countries` | `["us", "gb", "de"]`
|
|
59
|
-
| `industries` | `["SaaS", "Fintech"]`
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `keywords` | `["payments", "infrastructure"]` | Keyword filter |
|
|
63
|
-
| `ecommerce` | `true` | E-commerce companies only |
|
|
64
|
-
| `minScore` | `0.5` | Minimum similarity score (0–1) |
|
|
54
|
+
| Filter | Example | Notes |
|
|
55
|
+
| ------------------ | ------------------------------ | ------------------------------------------------------------ |
|
|
56
|
+
| `lookalikeDomains` | `["stripe.com", "plaid.com"]` | Core input — seed domains to find lookalikes for |
|
|
57
|
+
| `companySizes` | `["51-200", "201-500"]` | Filter by employee count range |
|
|
58
|
+
| `countries` | `["us", "gb", "de"]` | Two-letter ISO country codes |
|
|
59
|
+
| `industries` | `["SaaS", "Fintech"]` | Industry category names |
|
|
60
|
+
| `ecommerce` | `true` | E-commerce companies only |
|
|
61
|
+
| `peopleFilters` | `{ seniorities: ["C-Level"] }` | Top-level filter. Only return companies with matching people |
|
|
65
62
|
|
|
66
63
|
**Pagination:** Use `searchAfter` from the previous response for efficient cursor-based pagination. Max `size` per request is 100.
|
|
67
64
|
|
|
65
|
+
**Do not send these fields to `services.ocean.search.companies`:**
|
|
66
|
+
|
|
67
|
+
- `excludeDomains`
|
|
68
|
+
- `includeDomains`
|
|
69
|
+
- `from`
|
|
70
|
+
- `minScore`
|
|
71
|
+
- `technologyCategories`
|
|
72
|
+
- `revenueRanges`
|
|
73
|
+
|
|
74
|
+
Ocean v3 rejects each of those with `422`.
|
|
75
|
+
|
|
76
|
+
**Fields that are not safe as simple string arrays:** `technologies` and `keywords`.
|
|
77
|
+
|
|
78
|
+
When sent as string arrays, Ocean v3 returns `422` with `Input should be a valid dictionary or object to extract fields from`. Until we document the exact upstream shape, do not have the agent generate them.
|
|
79
|
+
|
|
68
80
|
### 2. `services.ocean.search.people` — Find People at Companies
|
|
69
81
|
|
|
70
82
|
Combine company filters with people filters to find the right contacts.
|
|
@@ -150,5 +162,5 @@ for (let page = 0; page < 5; page++) {
|
|
|
150
162
|
|
|
151
163
|
- **More seed domains = better results.** 3-5 seeds produce much better lookalikes than a single domain.
|
|
152
164
|
- **Combine with enrichment.** Ocean.io returns firmographic data, but you can enrich further with LinkedIn, BuiltWith, or PredictLeads.
|
|
153
|
-
- **
|
|
165
|
+
- **Exclude seed domains client-side.** Ocean v3 rejects `excludeDomains`, so filter out seed domains after the response if needed.
|
|
154
166
|
- **Credits:** 5 credits per result. A search returning 50 companies = 250 credits. Reserve is based on the requested `size`.
|
|
@@ -87,7 +87,7 @@ When using qualification columns, think Circle & Star:
|
|
|
87
87
|
| **Web Search (Default)** | **ALL prospecting/discovery** — keywords, niche, fuzzy, specific, LinkedIn profiles & companies via `site:linkedin.com` | Requires verification columns for false positives. |
|
|
88
88
|
| **Crunchbase (Funding Default)** | Funding-focused prospecting: stage, round type, amount, recency, investors | Best for funding intelligence; use other sources for non-funding discovery criteria. |
|
|
89
89
|
| **Ocean.io (Lookalike Default)** | User has seed domains and wants similar companies/people. "Find companies like X." | Needs seed domains as input. Not for keyword/niche discovery from scratch. See [guide](../lookalike-search/). |
|
|
90
|
-
| **PredictLeads** | Company intelligence, buying signals, and structured company events at scale | Coverage varies by company/market
|
|
90
|
+
| **PredictLeads** | Company intelligence, buying signals, and structured company events at scale | Coverage varies by company/market. Treat it as a prospecting/enrichment signal, not source-of-truth validation for whether a known company currently has an opening. |
|
|
91
91
|
| **Niche Directory Scrape** | Well-defined categories with existing lists (see below) | Requires finding the right directory first. |
|
|
92
92
|
| **LinkedIn B2B DB** | **Almost never for prospecting.** Only for: (1) lookups by known identifier (URL/domain/ID), (2) employees at a single known company, (3) trivially simple single-indexed-column filters like `industry_code` or `country_code`. | **Any query with keywords, descriptions, names, ILIKE, skills, or multi-criteria = web search.** The bar is extremely high — if in doubt, use web search. |
|
|
93
93
|
| **Google Maps** | Local/SMB, physical locations, restaurants, retail | Limited to businesses with physical presence. |
|
|
@@ -99,7 +99,7 @@ Use PredictLeads first when the user needs **high-quality structured company dat
|
|
|
99
99
|
|
|
100
100
|
PredictLeads is usually the best choice for:
|
|
101
101
|
- Tracking **company signals over time** (news, financing, hiring, tech detections, product changes, website evolution)
|
|
102
|
-
- Pulling **normalized lists** (job openings, technologies, investors/connections, similar companies) without custom scraping
|
|
102
|
+
- Pulling **normalized lists** (job openings, technologies, investors/connections, similar companies) for prospecting/enrichment without custom scraping
|
|
103
103
|
- Building qualification columns where consistency matters more than recall
|
|
104
104
|
- Workflows that need stable structured fields instead of parsing search snippets
|
|
105
105
|
|
|
@@ -9,8 +9,8 @@ description: Technographic data enrichment — discover what technologies, frame
|
|
|
9
9
|
|
|
10
10
|
| Method | Description | Credits |
|
|
11
11
|
| --------------- | -------------------------------------- | ------- |
|
|
12
|
-
| `lookupDomain` | Get full technology stack for a domain |
|
|
13
|
-
| `relationships` | Find related/connected domains |
|
|
12
|
+
| `lookupDomain` | Get full technology stack for a domain | 20 |
|
|
13
|
+
| `relationships` | Find related/connected domains | 10 |
|
|
14
14
|
| `searchByTech` | Find companies using a specific tech | 100 |
|
|
15
15
|
|
|
16
16
|
## Use Cases
|