Search for potential customers in the hotel and travel industry and B2B scenarios using structured criteria, and after confirmation, bulk import them into the CRM.
API
Base URL: http://39.108.114.224:9059
The request body of all endpoints must include the user_key field.
Endpoint list
| Function | Method | Path |
|---|---|---|
| Search customer profiles | POST | /skill/search_customer_profile |
| Bulk import customers | POST | /skill/batch_import_customer |
Invocation method
# 搜索客户画像
curl -s -X POST -H "Content-Type: application/json" \
"http://39.108.114.224:9059/skill/search_customer_profile" \
-d '{
"user_key": "<user_key>",
"q_keywords": "hotel hospitality resort",
"organization_locations": ["Japan"],
"person_titles": ["Business Development", "Partnership Manager"],
"person_seniorities": ["manager", "director", "head"],
"contact_email_status": ["verified", "likely to engage"],
"per_page": 10,
"page": 1
}'
# 批量导入客户
curl -s -X POST -H "Content-Type: application/json" \
"http://39.108.114.224:9059/skill/batch_import_customer" \
-d '{
"user_key": "<user_key>",
"customers": [
{
"name": "Hilton Tokyo",
"contact_name": "John Smith",
"contact_email": "john@hiltontokyo.com",
"contact_phone": "80012345",
"contact_phone_prefix": "+81",
"country_code": "JP",
"address": "Tokyo, Japan",
"remark": "Business Development | Hospitality"
}
]
}'
Response format
Success response:
{
"ok": true,
"data": { ... }
}
Failure response:
{
"ok": false,
"error": "错误描述"
}
search_customer_profile On success, the data field:
{
"total_entries": 120,
"credits_consumed": 5,
"customers": [
{
"name": "公司名",
"contact_name": "联系人",
"contact_email": "email@example.com",
"contact_phone": "12345678",
"contact_phone_prefix": "+81",
"country_code": "JP",
"address": "Tokyo, Japan",
"remark": "Title | Industry"
}
]
}
batch_import_customer On success, the data field:
{
"success_count": 8,
"fail_count": 2,
"fail_details": [
{"name": "公司名", "email": "xxx@example.com", "reason": "联系邮箱已存在"}
]
}
Core workflow
1. 用户描述目标客户
2. 你将自然语言拆解为 Apollo 可识别的结构化参数
3. 调用 /skill/search_customer_profile
4. 展示结果并询问是否导入
5. 用户确认后调用 /skill/batch_import_customer
Business context (important)
This company is a B2B service provider in the hotel and travel industry, and its core target customers mainly include:
- Hotels: hotel, resort, hospitality group, serviced apartment
- Travel: travel, tourism, tour operator, travel agency
- OTA / distribution: OTA, online travel agency, wholesaler, bedbank, distribution
- Business travel: business travel, corporate travel, TMC
- Local reception / destination services: DMC, destination management
Target contacts are preferably:
- Business development leads: Business Development, Partnership, Commercial
- Procurement / contracting leads: Procurement, Contracting, Sourcing, Supplier
- Hotel revenue / channel leads: Revenue, Distribution, Ecommerce
- Senior decision-makers: Founder, Owner, CEO, GM, VP, Head, Director
Setup
User identity verification must be completed before calling any endpoint.
Step 1 - User Key
- Read
{baseDir}/user_key.txt - If the file does not exist or is empty, do not call any endpoint, and tell the user:
"Before we start, we need to verify your identity. Please go to https://aauth-170125614655.asia-northeast1.run.app/dashboard to log in with your Google account, copy your
user_key(format:uk_xxxxxxxx), and then tell me." - If the file exists and has content, use its value as the
user_key - If any endpoint returns HTTP 401 or the response body
{"ok": false, "error": "unauthorized: ..."}, delete{baseDir}/user_key.txtand re-execute step 2
Endpoint parameter description
/skill/search_customer_profile
| Parameter | Type | Description |
|---|---|---|
| user_key | string | Read from {baseDir}/user_key.txt Read |
| q_keywords | string | English keywords, separate multiple words with spaces |
| person_titles | string[] | Contact job title |
| person_locations | string[] | Contact region |
| organization_locations | string[] | Company region, preferably use |
| person_seniorities | string[] | Contact level |
| contact_email_status | string[] | Email status |
| organization_num_employees_ranges | string[] | Company headcount range |
| revenue_range_min | int | Minimum revenue (USD) |
| revenue_range_max | int | Maximum revenue (USD) |
| per_page | int | Number per page |
| page | int | Page number, starting from 1 |
/skill/batch_import_customer
| Parameter | Type | Description |
|---|---|---|
| user_key | string | Read from {baseDir}/user_key.txt read |
| customers | CustomerItem[] | Customer list to import |
CustomerItem fields:
| Field | Type | Description |
|---|---|---|
| name | string | Customer or company name (required) |
| contact_name | string | Contact name (required) |
| contact_email | string | Contact email (required) |
| contact_phone | string | Contact phone (required) |
| contact_phone_prefix | string | Phone area code, e.g. +81 |
| country_code | string | Country code, e.g. JP |
| address | string | Address |
| remark | string | Notes or persona description |
Apollo search principles (very important)
This Apollo API set is essentially people search, not directly finding companies from a single persona description.
The correct approach is:
- First define the company persona
- Then define the contact persona
- Finally add filters such as email status, size, revenue, etc.
In other words, when constructing parameters you should prioritize:
q_keywords: industry and business model keywordsorganization_locations: company regionperson_titles: contact job titleperson_seniorities: contact seniority
Do not stuff the user's entire sentence into Apollo.
In particular, q_keywords:
- must be converted to English keywords
- should be short, precise, and searchable
- do not pass Chinese
- do not pass long sentences
- do not write only a vague term such as
B2B
Parameter parsing guide (must be followed)
1. First determine which category the search intent belongs to
First classify the user's need into one of the following business scenarios:
- Hotel / hotel group
- OTA / online travel platform
- Travel agency / tour operator
- Distribution / wholesale / wholesaler / bedbank
- Corporate travel / corporate travel / TMC
- Ground handling / DMC
If the user does not explicitly specify an industry, default to searching by hospitality and travel B2B prospects .
2. q_keywords rules
Recommended mapping:
| User expression | q_keywords |
|---|---|
| Hotel customers | hotel hospitality resort |
| Hotel groups | hotel hospitality group |
| OTA customers | ota online travel agency |
| Travel agencies | travel agency tour operator |
| Hospitality and travel distribution / wholesale | hotel wholesale travel distribution bedbank |
| Corporate travel customers | business travel corporate travel tmc |
| Ground handling / DMC | destination management dmc inbound travel |
| Hospitality and travel B2B customers | hotel travel hospitality b2b |
| Industry not specified | hotel travel hospitality b2b |
3. Region rules
By default, prefer organization_locations, because we usually want customers based on "which market the company is in".
Common region mapping:
| User expression | Parameter | Value |
|---|---|---|
| Japan customers | organization_locations | ["Japan"] |
| Tokyo customers | organization_locations | ["Tokyo"] |
| Southeast Asia customers | organization_locations | ["Singapore", "Thailand", "Vietnam", "Indonesia", "Malaysia", "Philippines"] |
| Europe customers | organization_locations | ["United Kingdom", "Germany", "France", "Spain", "Italy", "Netherlands"] |
| Middle East customers | organization_locations | ["United Arab Emirates", "Saudi Arabia", "Qatar"] |
| Hong Kong customers | organization_locations | ["Hong Kong"] |
4. person_titles rules
Recommended mapping:
| User expression | person_titles |
|---|---|
| Business development lead | ["Business Development", "Business Development Manager", "Partnership Manager", "Head of Partnerships", "Commercial Director"] |
| Procurement lead | ["Procurement Manager", "Purchasing Manager", "Sourcing Manager", "Buyer"] |
| Contracting lead | ["Contracting Manager", "Supplier Manager", "Market Manager"] |
| Hotel channel / revenue lead | ["Revenue Manager", "Distribution Manager", "Ecommerce Manager"] |
| Boss / Decision Maker | ["CEO", "Founder", "Owner", "General Manager", "Managing Director"] |
| No contact role specified | titles can be left empty, but seniorities must be filled in |
5. person_seniorities rules
- When no role is specified, default to:
["manager", "director", "head", "vp"] - Explicitly looking for boss / decision maker:
["owner", "founder", "c_suite"] - Explicitly looking for mid-level execution leads:
["manager", "director", "head"] - When there are too few results, you can relax to:
["manager", "director", "head", "vp", "c_suite"]
6. contact_email_status rules
Default to using:["verified", "likely to engage"]
Only when the user explicitly asks for "higher email quality" should you tighten to:["verified"]
7. Company size / revenue rules
| User expression | Parameter | Value |
|---|---|---|
| Large company | organization_num_employees_ranges | ["500,10000"] |
| Mid-sized company | organization_num_employees_ranges | ["50,500"] |
| Small and medium-sized enterprise | organization_num_employees_ranges | ["10,500"] |
| Annual revenue over 1 million USD | revenue_range_min | 1000000 |
8. Quantity rules
- Default
per_page=10 - When the user says "find 5", use
5 - Do not pass a
per_page
Search strategy (very important)
Round 1: Ensure hits first
- Use industry terms + business model terms to generate
q_keywords - Use
organization_locationsto limit the region person_senioritiesshould not be too strict at firstcontact_email_statusdefault to using["verified", "likely to engage"]
Round 2: Automatically relax when there are too few results
If the first round returns 0 results, or clearly too few (fewer than 3), relax in the following order and call again:
- Relax
person_seniorities - Remove
person_titles, keeping only industry terms and region - Keep the core industry terms and reduce overly specific business model terms
- If the user's region is too narrow, you can relax to a larger country/region level
Usage guide
Step 1: Understand and parse
After receiving the user's request, first complete the parsing: industry category, region, contact role, contact seniority, company size, then convert them into Apollo parameters.
Step 2: Call search and display results
After calling /skill/search_customer_profile , respond in the following format:
根据您的需求,我使用以下条件搜索:
- 关键词:{q_keywords}
- 公司地区:{organization_locations}
- 联系人岗位:{person_titles}
- 联系人层级:{person_seniorities}
共找到 {total_entries} 条匹配记录,本次获取 {count} 条:
1. {name}
联系人:{contact_name}
职位/备注:{remark}
邮箱:{contact_email}
电话:{contact_phone_prefix} {contact_phone}
地区:{country_code}
地址:{address}
是否要将这些客户录入 CRM 系统?也可以输入"下一页"查看更多。
Step 3: Confirm import
When the user replies with affirmative words such as "yes", "okay", "import", "enter", "confirm", call /skill/batch_import_customer。
Step 4: Import feedback
导入完成!成功 {success_count} 条,失败 {fail_count} 条。
如有失败,列出失败明细和原因。
Scenario templates
Template 1: Find hotel partnership leads in Japan
{
"q_keywords": "hotel hospitality resort",
"organization_locations": ["Japan"],
"person_titles": ["Business Development", "Partnership Manager", "Commercial Director", "Revenue Manager", "Distribution Manager"],
"person_seniorities": ["manager", "director", "head", "vp"],
"contact_email_status": ["verified", "likely to engage"],
"per_page": 10
}
Template 2: Find hotel distribution / wholesale clients in Southeast Asia
{
"q_keywords": "hotel wholesale travel distribution bedbank",
"organization_locations": ["Singapore", "Thailand", "Vietnam", "Indonesia", "Malaysia", "Philippines"],
"person_titles": ["Contracting Manager", "Supplier Manager", "Market Manager", "Business Development Manager"],
"person_seniorities": ["manager", "director", "head"],
"contact_email_status": ["verified", "likely to engage"],
"per_page": 10
}
Template 3: Find business travel / TMC clients in Europe
{
"q_keywords": "business travel corporate travel tmc",
"organization_locations": ["United Kingdom", "Germany", "France", "Spain", "Italy", "Netherlands"],
"person_titles": ["Head of Partnerships", "Commercial Director", "Business Development Director"],
"person_seniorities": ["director", "head", "vp"],
"contact_email_status": ["verified", "likely to engage"],
"per_page": 10
}
Notes
- When the API returns HTTP 401 or
ok: falseand the error containsunauthorized, delete{baseDir}/user_key.txtand re-guide the user to obtain user_key q_keywordsmust be English keywords, not Chinese sentences- By default, prefer using
organization_locations, notperson_locations - For the default email status, it is recommended to use
["verified", "likely to engage"] - By default, fetch at most 10 records each time; get more results through pagination
- When importing, email, contact, phone, and company name are key fields