Divar API Skill
Divar uses a server-driven widget API (JSON over HTTPS, protobuf type annotations embedded via @type).
All responses are lists of typed widget_type objects. Base URL: https://api.divar.ir.
Critical: form_data field types
Every filter field uses a typed wrapper. Wrong type = HTTP 400. Use this table exactly:
| Field | Wrapper | Example |
|---|
| INLINECODE3 | INLINECODE4 | INLINECODE5 |
| INLINECODE6 |
str |
{ "str": { "value": "sort_date" } } |
|
districts |
repeated_string |
{ "repeated_string": { "value": ["920", "82"] } } |
|
rooms |
repeated_string |
{ "repeated_string": { "value": ["یک", "دو"] } } |
|
rent |
number_range |
{ "number_range": { "minimum": "20000000", "maximum": "60000000" } } |
|
credit |
number_range |
{ "number_range": { "minimum": "300000000", "maximum": "600000000" } } |
|
size |
number_range |
{ "number_range": { "minimum": "80", "maximum": "120" } } |
|
balcony |
boolean |
{ "boolean": { "value": true } } |
|
parking |
boolean |
{ "boolean": { "value": true } } |
INLINECODE30 min/max values are strings, not numbers.
boolean value is a JS boolean (true/false), not a string.
Critical: category slugs
The API slug differs from the divar.ir URL path segment. Never use the URL segment as the slug.
API slug (category.str.value) | URL path | Persian |
|---|
| INLINECODE35 | INLINECODE36 | اجاره مسکونی |
| INLINECODE37 |
apartment-sell | فروش آپارتمان |
|
apartment-rent |
rent-apartment | اجاره آپارتمان |
|
buy-residential |
buy-residential | فروش مسکونی |
|
real-estate |
real-estate | همه ملک |
|
buy-commercial-property |
buy-commercial-property | فروش اداری/تجاری |
|
rent-commercial-property |
rent-commercial-property | اجاره اداری/تجاری |
|
rent-temporary |
rent-temporary | اجاره کوتاهمدت |
When in doubt, intercept a real browser request via DevTools to read the actual category.str.value.
Search endpoint
INLINECODE52
Verified working payload (residential rental, Tehran, tested 2026-04-01 → returned 24 listings):
CODEBLOCK0
Response: INLINECODE53
Filter to widget_type === "POST_ROW" to get listings. Each POST_ROW has:
- -
data.title — listing title (Persian) - INLINECODE56 — price string
- INLINECODE57 — relative time ("دقایقی پیش")
- INLINECODE58 — unique post ID (use for detail/contact endpoints)
- INLINECODE59 — district name
- INLINECODE60 — number of photos
Pagination
Cursor-based. On page 1, no pagination_data. On page 2+, add:
CODEBLOCK1
INLINECODE62 is an optional gzip+base64 bloom filter for server-side deduplication — safe to omit.
Post detail
INLINECODE63
Returns sections (BREADCRUMB, HEADER, IMAGES, DETAILS) each containing widget arrays.
Common detail widget types: KEY_VALUE (room count, floor, etc.), DESCRIPTION, IMAGE_GALLERY, MAP.
Contact info (requires auth)
INLINECODE72
Body: {}. Returns widget_list with UNEXPANDABLE_ROW containing phone number.
Returns RBAC: access denied without authentication.
Authentication
- - Cookie-based:
token cookie + did (device ID) cookie, set by divar.ir on login. - Header:
Authorization: Basic <jwt> — same JWT value as the token cookie. - The search endpoint works with session cookies alone when called same-origin from
divar.ir. - Cross-origin calls (e.g. from a script) need the
Authorization header explicitly.
Parsing a divar.ir search URL → API payload
When a user pastes a URL like:
INLINECODE83
Map query params to form_data fields:
| URL param | form_data field | Wrapper |
|---|
URL path segment (e.g. rent-residential) | INLINECODE86 → look up API slug | INLINECODE87 |
| INLINECODE88 |
districts |
repeated_string (split on
,) |
|
rooms=دو,یک |
rooms |
repeated_string (split on
,) |
|
rent=min-max |
rent |
number_range (split on
-) |
|
credit=min-max |
credit |
number_range (split on
-) |
|
size=min-max |
size |
number_range (split on
-) |
|
balcony=true |
balcony |
boolean |
|
parking=true |
parking |
boolean |
|
map_bbox=... | not in form_data — belongs in
/v8/mapview/viewport camera_info.bbox | — |
|
map_place_hash=... | not in form_data | — |
For full API reference (all endpoints, widget system, map/geo, autocomplete, filters):
→ read INLINECODE118
Divar API 技能
Divar 使用服务端驱动的微件 API(基于 HTTPS 的 JSON,通过 @type 嵌入 protobuf 类型注解)。
所有响应均为带类型的 widget_type 对象列表。基础 URL:https://api.divar.ir。
关键:form_data 字段类型
每个筛选字段都使用类型化包装器。类型错误 = HTTP 400。 请严格使用此表:
| 字段 | 包装器 | 示例 |
|---|
| category | str | { str: { value: residential-rent } } |
| sort |
str | { str: { value: sort_date } } |
| districts | repeated
string | { repeatedstring: { value: [920, 82] } } |
| rooms | repeated
string | { repeatedstring: { value: [یک, دو] } } |
| rent | number
range | { numberrange: { minimum: 20000000, maximum: 60000000 } } |
| credit | number
range | { numberrange: { minimum: 300000000, maximum: 600000000 } } |
| size | number
range | { numberrange: { minimum: 80, maximum: 120 } } |
| balcony | boolean | { boolean: { value: true } } |
| parking | boolean | { boolean: { value: true } } |
number_range 的最小/最大值是字符串,而非数字。
boolean 的值是 JS 布尔值(true/false),而非字符串。
关键:分类标识符
API 标识符与 divar.ir 的 URL 路径段不同。切勿将 URL 段用作标识符。
| API 标识符(category.str.value) | URL 路径 | 波斯语 |
|---|
| residential-rent | rent-residential | اجاره مسکونی |
| apartment-sell |
apartment-sell | فروش آپارتمان |
| apartment-rent | rent-apartment | اجاره آپارتمان |
| buy-residential | buy-residential | فروش مسکونی |
| real-estate | real-estate | همه ملک |
| buy-commercial-property | buy-commercial-property | فروش اداری/تجاری |
| rent-commercial-property | rent-commercial-property | اجاره اداری/تجاری |
| rent-temporary | rent-temporary | اجاره کوتاهمدت |
如有疑问,请通过开发者工具拦截真实浏览器请求,读取实际的 category.str.value。
搜索端点
POST /v8/postlist/w/search
已验证可用的请求体(住宅租赁,德黑兰,测试于 2026-04-01 → 返回 24 条列表):
json
{
city_ids: [1],
source_view: SEARCH,
disable_recommendation: false,
search_data: {
form_data: {
data: {
category: { str: { value: residential-rent } },
districts: { repeated_string: { value: [139,143,145,4162,75,78,82,920,921] } },
rooms: { repeated_string: { value: [دو,یک] } },
rent: { number_range: { minimum: 20000000, maximum: 60000000 } },
credit: { number_range: { minimum: 300000000, maximum: 600000000 } },
size: { number_range: { minimum: 80, maximum: 120 } },
balcony: { boolean: { value: true } },
parking: { boolean: { value: true } }
}
},
server_payload: {
@type: type.googleapis.com/widgets.SearchData.ServerPayload,
additionalformdata: {
data: { sort: { str: { value: sort_date } } }
}
}
}
}
响应: { listtopwidgets: [...], list_widgets: [...] }
筛选 widgettype === POSTROW 以获取列表。每个 POST_ROW 包含:
- - data.title — 列表标题(波斯语)
- data.middledescriptiontext — 价格字符串
- data.bottomdescriptiontext — 相对时间(دقایقی پیش)
- data.action.payload.token — 唯一帖子 ID(用于详情/联系端点)
- data.action.payload.webinfo.districtpersian — 区域名称
- data.image_count — 照片数量
分页
基于游标。第 1 页无需 pagination_data。第 2 页起需添加:
json
{
pagination_data: {
@type: type.googleapis.com/post_list.PaginationData,
lastpostdate: <上一最后帖子的 ISO8601 时间>,
page: 2,
layer_page: 2,
search_uid: ,
cumulativewidgetscount: 24
}
}
viewed_tokens 是可选的服务端去重布隆过滤器(gzip+base64 编码)——可安全省略。
帖子详情
GET /v8/posts-v2/web/{token}
返回包含微件数组的各个部分(BREADCRUMB、HEADER、IMAGES、DETAILS)。
常见的详情微件类型:KEYVALUE(房间数、楼层等)、DESCRIPTION、IMAGEGALLERY、MAP。
联系信息(需认证)
POST /v8/postcontact/web/contactinfov2/{token}
请求体:{}。返回包含电话号码的 UNEXPANDABLEROW 的 widgetlist。
未认证时返回 RBAC: access denied。
认证
- - 基于 Cookie:token cookie + did(设备 ID)cookie,由 divar.ir 在登录时设置。
- 请求头:Authorization: Basic — 与 token cookie 相同的 JWT 值。
- 从 divar.ir 同源调用时,搜索端点仅使用会话 cookie 即可工作。
- 跨域调用(例如从脚本调用)需要显式提供 Authorization 请求头。
解析 divar.ir 搜索 URL → API 请求体
当用户粘贴如下 URL 时:
https://divar.ir/s/tehran/rent-residential/almahdi?balcony=true&credit=300000000-600000000&districts=920%2C82&rent=20000000-60000000&rooms=%D8%AF%D9%88%2C%DB%8C%DA%A9&size=80-120
将查询参数映射到 form_data 字段:
| URL 参数 | formdata 字段 | 包装器 |
|---|
| URL 路径段(例如 rent-residential) | category → 查找 API 标识符 | str |
| districts=920,82,... |
districts | repeatedstring(按 , 分割) |
| rooms=دو,یک | rooms | repeated_string(按 , 分割) |
| rent=min-max | rent | number_range(按 - 分割) |
| credit=min-max | credit | number_range(按 - 分割) |
| size=min-max | size | number_range(按 - 分割) |
| balcony=true | balcony | boolean |
| parking=true | parking | boolean |
| map
bbox=... | 不在 formdata 中 — 属于 /v8/mapview/viewport 的 camera_info.bbox | — |
| map
placehash=... | 不在 form_data 中 | — |
如需