Listing Posts

REST endpoints to prepare a post from one of your listings, edit its caption, publish it or schedule it to your own Instagram or LinkedIn, and reply to a comment that is an enquiry.

Overview

A listing post is one post of one of your agency's listings to your own connected Instagram (a feed post or a story) or LinkedIn. Fondaro renders the slides from the listing and writes a caption from its description; you publish it or schedule it.

Nothing is posted without a person's action: only publish and schedule reach Instagram or LinkedIn, and a scheduled post goes out once, within five minutes of its time. Drafts that Fondaro prepares on its own (when a listing goes live or its price changes) wait in the Inbox as post_draft rows.

The endpoints use the dashboard's Clerk bearer token and resolve the organization from the request. Every route is your own: posts on accounts you connected, and drafts you made. Writes need an active plan, as on the CRM endpoints. A sandbox organization cannot publish.

Endpoints

Method & pathPurpose
GET /listing-posts?listingId&statusYour posts, newest first (at most 100)
GET /listing-posts/:idOne post
GET /listing-posts/linkedin-pagesThe LinkedIn company pages you can post as
GET /listing-posts/:id/engagementLikes, comments and impressions of a published post
POST /listing-postsPrepare a draft from a listing
PATCH /listing-posts/:idChange the caption, feed or story, or the LinkedIn page
POST /listing-posts/:id/publishPublish now
POST /listing-posts/:id/schedulePublish at a time
POST /listing-posts/:id/unscheduleBack to a draft
DELETE /listing-posts/:idDiscard a post that has not gone out
POST /listing-posts/comments/:messageId/replyReply under a comment that is an enquiry

The post object

FieldTypeNotes
idstring
listingobjectref ({ source: "internal", id }), reference, location
accountobject or nullid, kind (instagram or linkedin), address, status; null once the account was removed
channelstringinstagram or linkedin
kindstringfeed or story (Instagram only)
linkedinOrganizationIdstring or nullLinkedIn only: the company page it goes out as; null posts as you
captionstringAt most 2,200 characters
mediaarray{ url, width, height } per rendered slide, in posting order
scheduledAtstring or nullWhen it goes (or went) out
statusstringdraft, scheduled, publishing, published, failed or needs_reconnect
providerPostId, providerPostUrlstring or nullSet once published; the link when Instagram or LinkedIn reports one
createdBystring or nullClerk user id; null when Fondaro drafted it
createdAt, updatedAtstringISO 8601

An Instagram feed post goes out as the listing's cover slide for now; a LinkedIn post carries up to four slides. A post whose account stopped working becomes needs_reconnect; reconnect the account, then publish again. A failed post is never sent again unless you publish it.

Prepare a draft

curl -X POST https://api.fondaro.com/listing-posts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "listingId": "2d3d0669-0dc5-4e80-b573-b543a59fcd29", "channel": "instagram", "kind": "feed", "language": "es" }'

To post on LinkedIn as a company page, add "linkedinOrganizationId" with an id from GET /listing-posts/linkedin-pages, which reads your pages from your LinkedIn when you ask ({ "pages": [{ "id", "name" }] }, empty without a working LinkedIn). A page you cannot post as is a 400.

language picks the caption's language (the listing's description in that language when it has one); it defaults to your organization's first language. The response is the post object with status: "draft".

StatusBody codeWhen
400A story on LinkedIn; the listing has no price, town, public photo or agency name
404Not one of your organization's listings
409LISTING_POST_NO_ACCOUNTYou have no connected account on that channel

Change the caption, feed or story, or the page

curl -X PATCH https://api.fondaro.com/listing-posts/$POST_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "caption": "Estepona. €1,250,000. Three terraces over the sea." }'

The body takes any of caption, kind (feed or story; changing it renders the slides again and keeps the caption; a story is Instagram only) and linkedinOrganizationId (a page id, or null to post as you). Allowed while the post is draft, scheduled, failed or needs_reconnect; otherwise 409 with LISTING_POST_NOT_EDITABLE.

Publish now or schedule

curl -X POST https://api.fondaro.com/listing-posts/$POST_ID/publish \
  -H "Authorization: Bearer $TOKEN"

curl -X POST https://api.fondaro.com/listing-posts/$POST_ID/schedule \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "scheduledAt": "2026-10-02T18:00:00+02:00" }'

Both return the post. publish answers once Instagram or LinkedIn has taken it (published), or with needs_reconnect or failed. When the network is busy the post stays scheduled for now and goes out within five minutes. schedule needs a time at least a minute ahead and at most 90 days away (400 otherwise). Either answers 409 with LISTING_POST_NEEDS_RECONNECT when your account needs reconnecting, and 403 from a sandbox.

unschedule moves a scheduled post back to a draft; DELETE discards a post that has not gone out, with its slides (204).

Reply to a comment

Comments on your published posts are read about once an hour. A comment that is about the home is stored as a message of kind comment (on the lead, when the commenter is already linked to one, otherwise as a new conversation in your Inbox); nothing is stored for any other comment. Reply under it with the message id:

curl -X POST https://api.fondaro.com/listing-posts/comments/$MESSAGE_ID/reply \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "text": "Thank you, I have sent you the details by message." }'

Only the person whose account published the post can reply. The response is { "replied": true }, and the comment no longer waits in the Inbox.

Engagement

curl https://api.fondaro.com/listing-posts/$POST_ID/engagement \
  -H "Authorization: Bearer $TOKEN"

Returns { "likes", "comments", "impressions", "readAt" } for a published post, read from Instagram or LinkedIn when you ask (kept for five minutes, never stored). A count the network does not report is null; impressions are LinkedIn only. The response is empty (null) for a post that is not out or whose account cannot be read now.

On the calendar

Scheduled and published posts appear in GET /calendar as items of kind post. See Calendar.