Get started · 10 minutes
Quickstart
Before you start
You need an organization on the Enterprise plan, and an organization admin to create the key. Team plans can create keys too, for the integration endpoints (webhooks, lead bundles, write-back). Unlocking and revealing spend real credits; every example uses illustrative data.
1. Create an API key
- In the Greenfinch app, an organization admin opens Org admin → Integrations and chooses Create API key.
- Name the key after what will use it (for example “Prospecting sync — production”) and tick
data:readanddata:unlock. Neither is selected by default:data:unlockspends credits. - Copy the key. It starts with
gfk_and is shown once; Greenfinch stores only a hash, so a lost key cannot be recovered — revoke it and create another.
Keep the key out of source control. The examples read it from an environment variable:
export GREENFINCH_API_KEY="gfk_…"2. Check the key
GET /me needs no particular scope. It confirms the key is live and shows which scopes it carries.
curl "https://app.greenfinch.ai/api/v1/me" \
-H "Authorization: Bearer $GREENFINCH_API_KEY"{
"success": true,
"data": {
"org_id": "org_example000000000001",
"credential_id": "3f2a9c1e-0000-4000-8000-000000000901",
"scopes": [
"data:read",
"data:unlock"
],
"label": "Prospecting sync — production (gfk_Xk2pQ9aB)"
}
}A 401 means the key is wrong or revoked; a 403 with UPGRADE_REQUIRED means your plan does not include the scope you called. See Limits and errors.
3. Find a property by its address
Send a free-text query — it matches addresses, cities, owners and property names. To search by criteria instead, send filters with a county, ZIP or city (see Search properties).
curl -X POST "https://app.greenfinch.ai/api/v1/properties/search" \
-H "Authorization: Bearer $GREENFINCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "1200 Commerce Pkwy, Plano, TX",
"limit": 5
}'{
"success": true,
"data": {
"results": [
{
"id": "3f2a9c1e-0000-4000-8000-000000000001",
"address": "1200 Commerce Pkwy",
"city": "Plano",
"state": "TX",
"zip": "75074",
"county": "Collin",
"owner": "Northgate Business Park LLC",
"commonName": "Northgate Business Park",
"assetCategory": "Office",
"buildingSqft": 96000,
"yearBuilt": 2004,
"enrichmentStatus": "completed"
}
],
"has_more": false,
"next_cursor": null,
"sorted_by": {
"field": "relevance",
"direction": "desc"
},
"searched_scope": {
"scoped": true,
"countyCount": 2,
"states": [
"TX"
]
}
}
}Keep the property's id. It is the Greenfinch ID every other call uses; store it next to your own record.
4. Read the property
Reading costs nothing. The detail tells you what you can see and what unlocking would add:
curl "https://app.greenfinch.ai/api/v1/properties/3f2a9c1e-0000-4000-8000-000000000001/detail" \
-H "Authorization: Bearer $GREENFINCH_API_KEY"{
"success": true,
"data": {
"property": {
"id": "3f2a9c1e-0000-4000-8000-000000000001",
"address": "1200 Commerce Pkwy",
"city": "Plano",
"state": "TX",
"assetCategory": "Office",
"buildingSqft": 96000,
"beneficialOwner": null,
"managementCompany": null,
"aiRationale": null
},
"contacts": [],
"contactsSummary": {
"totalCount": 2,
"contacts": [
{
"title": "Director of Facilities",
"availability": {
"email": true,
"phone": true,
"linkedin": true
}
},
{
"title": "Property Manager",
"availability": {
"email": true,
"phone": false,
"linkedin": true
}
}
]
},
"researchRevealed": false,
"researchState": "locked",
"revealSource": null,
"coveredByPlan": false
}
}researchState tells you what to do next: revealed means everything is already readable, locked means research exists and can be unlocked, and none means the property has not been researched yet.
5. Unlock it
One unlock costs 10 credits and opens the property's research and every contact attached to it. Calling it again is free.
curl -X POST "https://app.greenfinch.ai/api/v1/properties/3f2a9c1e-0000-4000-8000-000000000001/unlock" \
-H "Authorization: Bearer $GREENFINCH_API_KEY"{
"success": true,
"data": {
"alreadyRevealed": false,
"creditsCharged": 10
}
}A repeat answers { "alreadyRevealed": true, "creditsCharged": 0 }. If your organization is out of credits you get 402 with meta.required and meta.available; a property without research yet answers 409 NOT_RESEARCHED.
6. Read the decision-makers
Fetch the detail again. The contacts now carry names and contact details:
curl "https://app.greenfinch.ai/api/v1/properties/3f2a9c1e-0000-4000-8000-000000000001/detail" \
-H "Authorization: Bearer $GREENFINCH_API_KEY"{
"success": true,
"data": {
"property": {
"id": "3f2a9c1e-0000-4000-8000-000000000001",
"beneficialOwner": "Northgate Holdings Group",
"managementCompany": "Lakeside Property Services",
"…": "…"
},
"contacts": [
{
"id": "3f2a9c1e-0000-4000-8000-000000000011",
"fullName": "Dana Whitfield",
"title": "Director of Facilities",
"employerName": "Lakeside Property Services",
"email": "dana.whitfield@example.com",
"emailValidationStatus": "valid",
"phone": "(214) 555-0142",
"phoneLabel": "Direct",
"linkedinUrl": "https://www.linkedin.com/in/example-dana-whitfield",
"role": "property_manager",
"relationshipStatus": "active",
"revealed": true,
"…": "…"
}
],
"contactsSummary": null,
"researchRevealed": true,
"researchState": "revealed",
"revealSource": "paid",
"coveredByPlan": true
}
}7. Reveal one person
To reach someone you know by name or employer without unlocking a whole property, search contacts, then reveal just that person for 5 credits.
curl "https://app.greenfinch.ai/api/v1/contacts/search?query=Lakeside%20Property&limit=10" \
-H "Authorization: Bearer $GREENFINCH_API_KEY"{
"success": true,
"data": {
"contacts": [
{
"id": "3f2a9c1e-0000-4000-8000-000000000201",
"name": "Morgan Ellis",
"title": "Regional Property Manager",
"employer": "Lakeside Property Services",
"location": "Dallas, TX"
}
],
"note": null
}
}curl -X POST "https://app.greenfinch.ai/api/v1/contacts/3f2a9c1e-0000-4000-8000-000000000201/reveal" \
-H "Authorization: Bearer $GREENFINCH_API_KEY"{
"success": true,
"data": {
"contact": {
"id": "3f2a9c1e-0000-4000-8000-000000000201",
"fullName": "Morgan Ellis",
"email": "morgan.ellis@example.com",
"phone": "(214) 555-0167",
"phoneLabel": "Mobile",
"phoneFallbackFromEmployer": false,
"linkedinUrl": "https://www.linkedin.com/in/example-morgan-ellis",
"title": "Regional Property Manager",
"employerName": "Lakeside Property Services"
},
"creditsCharged": 5,
"alreadyRevealed": false
}
}A contact your organization already revealed, or who is attached to a property you unlocked, costs nothing. If your admins set a daily contact-reveal limit and it is used up, the answer is 429 with a Retry-After header.
On an Enterprise plan, each full record a program receives — a property, a firm or a person — also counts once per billing period against the records allowance your order states, whichever door it leaves by; searches and other summaries never do. See Limits and errors for the three levels and how to read what is left.
8. The same thing through MCP
Every step above also exists as an MCP tool. Use the MCP endpoint when an AI assistant or agent is doing the work, or for what REST does not offer yet — research, lists, pipeline changes and account tools. It is a normal HTTPS endpoint that takes JSON-RPC 2.0 requests with the same key (the key needs the mcp scope); no MCP library is required.
curl -X POST "https://app.greenfinch.ai/api/v1/mcp" \
-H "Authorization: Bearer $GREENFINCH_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "greenfinch_search_properties",
"arguments": {
"query": "1200 Commerce Pkwy, Plano, TX",
"limit": 5
}
}
}'{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{\n \"results\": [ … ] }"
}
],
"structuredContent": {
"results": [
{
"id": "3f2a9c1e-0000-4000-8000-000000000001",
"address": "1200 Commerce Pkwy",
"…": "…"
}
],
"has_more": false,
"next_cursor": null,
"sorted_by": {
"field": "relevance",
"direction": "desc"
},
"searched_scope": {
"scoped": true,
"countyCount": 2,
"states": [
"TX"
]
}
}
}
}MCP refusals are not HTTP errors
On MCP, a tool that refuses — out of territory, out of credits — still answers HTTP 200. The result has isError: true and structuredContent.code names the reason. The REST endpoints turn the same refusals into HTTP statuses. Details in MCP connector.
Next steps
Put properties on a list (REST), receive qualified leads automatically with webhooks, export CRM-ready lead bundles, or connect an AI assistant with the MCP connector.