Table of Contents(9)
- The Shift: From Models That Describe Software to Agents That Operate It
- What an Agent-Driven Media Pipeline Looks Like
- Agent, Script, Batch or Chat: Choosing the Route
- Worked Example: An Agent Staging a Listing Through an Image API
- Why Agents Need Deterministic Tools, Not Chat Interfaces
- The Failure Modes Nobody Budgets For
- What Still Belongs to a Human
- The Agent-Readiness Checklist for Proptech Teams
- The Bottom Line
What changed in this update
- Updated the API example: every tool the Roomagen API accepts is now documented, not just six
- Updated the note on option typos: tools other than staging now name each ignored option in a warnings list
Earlier updates(1)
- Added the cancelled GPT-6.1 Astra (28 September) and what it means for trusting an agent's own reports, plus current GPT-6 Astra and GPT-6.1 Sol API prices
- Corrected the prompt-injection result: 8.5% of test scenarios with 15 attempts each, not one hostile document in twelve
- Added a route guide (script, agent, app batch or chat), a narrow tool definition for agents, an error-code table with the action to take, and current API rate limits and refund rules
- Added California's rental-ad disclosure law (AB 2025, from January 2027), the state real estate regulator's AI advisory and a table of which actions need a person
AI agents such as GPT-6 Astra output text, not images, so they cannot make listing photos themselves. They can run the pipeline: sort photos, call an image API per photo, check results, log costs. People approve publishing, disclosure and spend.
Free AI Virtual Staging — Stage Any Empty Room in Under a Minute
Stage vacant rooms with AI, usually in under a minute. 13 design styles, 15 room types, listing-ready photos for real estate, rentals and hospitality. 6 free credits, no credit card required.
The Shift: From Models That Describe Software to Agents That Operate It
Until recently, an AI model's relationship with your property software was advisory. It could tell you what to write in the CRM. It could not open the CRM.
That boundary moved in September 2026. OpenAI announced GPT-6 Astra on 3 September with the line "Anything you can do on a computer, Astra can do for you", and reports 72.6% on the OSWorld 2.0 computer-use benchmark at about 40 minutes per task, against 65.7% at roughly 75 minutes for its predecessor, GPT-5.6 Sol. Astra takes text and images in and returns only text. Its API costs $10 per million input tokens and $50 per million output tokens at the standard rate, and OpenAI also lists GPT-6.1 Sol at a fifth of that ($2 / $10). Google's similarly named Project Astra is a separate research prototype used by a limited group of trusted testers.
For property media, this changes who pushes the buttons. A listing shoot has always been a sequence of software operations: upload, select, stage, enhance, convert, label, publish. All of them can now be automated end to end, which raises a question most proptech teams have not answered: what does your stack need to look like for an agent to drive it safely?
The short answer: the agent reads, sorts and checks; an image API makes the pixels; your code holds the keys, the budget and the disclosure rules; and a person approves anything a buyer, tenant or guest will see.
ChatGPT access, full prices and benchmark rankings are in GPT-6 Astra for Real Estate. This article is about the plumbing.
What an Agent-Driven Media Pipeline Looks Like
A photo-processing API is what makes this drivable: you send one photo and an instruction (a tool and its options) over HTTPS, and get back a job you can track until the edited image is ready. Around it, the loop for one listing looks like this:
| Step | What the agent does | What it calls | Who signs off |
|---|---|---|---|
| 1. Intake | Reads the listing record, pulls the photos | Your CRM or DAM | Nobody: read-only |
| 2. Triage | Sorts photos: stage, enhance, re-shoot, discard | Vision-language reasoning | Spot checks |
| 3. Brief | Picks room type and style per photo | Its own reasoning, within your style guide | The style guide limits the options |
| 4. Render | Submits one job per photo | An image API | Your code enforces the spend cap |
| 5. Wait | Receives webhooks, or polls | The same API | — |
| 6. Verify | Compares output with source for structural drift | Vision-language reasoning | A person reviews anything flagged |
| 7. Publish | Writes results back with disclosure and the original | Your CRM and portal feed | A person approves |
| 8. Report | Logs net cost, failures and retries | Your accounting | — |
Steps 2, 3, 6 and 8 are where an agentic model earns its keep. Step 4 is where it hands off, because GPT-6 Astra returns text, not images (see Can GPT-6 Astra Do Virtual Staging or Generate Images?).
The agent should call an API, not click through a web app. Computer use is a compatibility layer for software that has no API. When an API exists, using it is faster, cheaper, deterministic and, the part that matters at 3am, debuggable.
Hotels refreshing room photos, furniture retailers staging catalogue rooms and architecture studios turning plans into 3D views run the same loop; only the tools and the sign-off rules change.
Agent, Script, Batch or Chat: Choosing the Route
An autonomous agent is the heaviest option. Pick the lightest one that does the job:
| Your situation | Route that fits |
|---|---|
| Fixed rules, such as "every photo gets medium-intensity enhancement" | A plain script calling the API: no model to pay for or supervise |
| Per-photo decisions at volume, with photos already in your CRM or DAM | An agent calling the API |
| A few photos, one tool, no developer | Batch processing in the app: up to 3, 7 or 20 photos per run on Starter, Pro or Business |
| One photo that needs several rounds of changes | AI Design Chat: describe each change in plain words |
| Removing one specific object precisely | A person in the app's marking screen; API item removal works from a text description, not a drawn mask |
App batches land in a Library folder with a ZIP download, refund failed photos and take per-photo settings, such as windows, view and season for day to dusk interiors (Time Shift Interior in the app). Refine then takes a typed correction for a near-miss on staging, Empty Room, Remove Item or interior dusk results. Paid plans start at $12 a month (pricing); batch is not on the Free plan.
Worked Example: An Agent Staging a Listing Through an Image API
This example uses the Roomagen API because we can document its exact shape; the pattern generalizes to any job-based image API. It documents every tool it accepts (65 as of October 2026, including virtual-staging, virtual-renovation, image-enhancement, day-to-dusk, item-removal and floor-plan-to-3d), takes one image per job, and gives 50 free images on the first key.
Step 0: give the agent a narrow tool, not the API key. Most agent frameworks describe tools with JSON Schema. Limit it to what your style guide allows:
{
"name": "stage_listing_photo",
"description": "Stage one empty room from a listing. Returns a job_id; the image arrives later.",
"parameters": {
"type": "object",
"properties": {
"listing_id": { "type": "string" },
"photo_id": { "type": "string" },
"style": { "type": "string", "enum": ["modern", "scandinavian", "japandi", "coastal"] },
"roomType": { "type": "string", "enum": ["living-room", "bedroom", "dining-room", "home-office"] }
},
"required": ["listing_id", "photo_id", "style"]
}
}
Your code turns that call into the API request: it resolves the IDs to an image URL, adds the key, the webhook URL and the idempotency key, and checks the spend cap. The agent cannot invent a style, never sees a credential, and cannot be talked into submitting a URL from a hostile email.
Step 1: one job per photo. One header authenticates, and each job is one image and one tool, charged when it is created:
curl -X POST https://api.roomagen.com/api/v1/jobs \
-H "X-Api-Key: rmg_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: listing-8842-photo-03" \
-d '{
"tool": "virtual-staging",
"image_url": "https://cdn.yourapp.com/listings/8842/photo-03.jpg",
"options": { "style": "scandinavian", "roomType": "living-room" },
"webhook_url": "https://yourapp.com/hooks/roomagen"
}'
The response returns before generation finishes:
{
"job_id": "3f1c9d4e-5b2a-4c8e-9f10-7d6a2b3c4e5f",
"status": "processing",
"images_charged": 1
}
Four details matter more for an agent than for a human integrator:
Idempotency-Keyis the safety rail. The same key and body return the original job, with no second charge or render; the same key with a different body gets409 idempotency_conflict. Derive keys from your own record (listing ID plus photo ID), never at random, or retries will not match.images_chargedis the charge, not the net cost. Failed jobs are refunded automatically, but the field is not rewritten, so take net spend from completed jobs or fromimage_creditsinGET /api/v1/account.toolis just a slug. The same call runs AI photo enhancement, day to dusk photo editing, object & item removal or floor plan to 3D. FetchGET /api/v1/toolsinstead of hard-coding slugs an agent might invent, and validate options yourself: staging rejects unknown keys, while the other tools still run but name each ignored key in the response'swarningslist, so have the agent check that list.- There is no batch endpoint. A 40-photo shoot is 40 jobs, and job creation is limited to 60 a minute per key (a
429carriesRetry-After).
Step 2: the result arrives by webhook. When the job finishes, the API POSTs it to your endpoint with an event field (job.completed or job.failed):
{
"job_id": "3f1c9d4e-5b2a-4c8e-9f10-7d6a2b3c4e5f",
"tool": "virtual-staging",
"status": "completed",
"images_charged": 1,
"result_urls": ["https://api.roomagen.com/api/uploads/9c2f7a10-render.jpg"],
"error": null,
"created_at": "2026-09-06T09:14:02.114Z",
"completed_at": "2026-09-06T09:14:39.902Z",
"processing_ms": 37788,
"event": "job.completed"
}
Verify the signature before you trust a byte of it. The headers X-Roomagen-Event, X-Roomagen-Timestamp and X-Roomagen-Signature: v1=<hex> carry an HMAC-SHA256 over {timestamp}.{raw body}, keyed with your whsec_ secret:
const crypto = require("crypto");
function verify(rawBody, headers, secret) {
const ts = headers["x-roomagen-timestamp"];
const expected =
"v1=" + crypto.createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
const got = headers["x-roomagen-signature"];
if (got.length !== expected.length) return false;
if (!crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) return false;
return Math.abs(Date.now() / 1000 - Number(ts)) < 300;
}
Compute the digest over the raw body bytes, not re-serialized JSON, and reject timestamps older than about five minutes. Deliveries time out after 10 seconds and do not follow redirects; the webhook reference has the full contract.
Step 3: polling as the fallback. Webhooks fail, and a delivery is abandoned after five attempts over about 36 minutes. GET /api/v1/jobs/{id} returns the same object, so a supervisor loop can reconcile anything stuck in processing:
async function waitForJob(jobId, timeoutMs = 5 * 60 * 1000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const res = await fetch(`https://api.roomagen.com/api/v1/jobs/${jobId}`, {
headers: { "X-Api-Key": process.env.ROOMAGEN_API_KEY },
});
if (res.status === 429) {
const wait = Number(res.headers.get("Retry-After") || 5);
await new Promise((r) => setTimeout(r, wait * 1000));
continue;
}
const body = await res.json();
if (!res.ok) throw new Error(body.error.code); // e.g. job_not_found, key_revoked
if (body.status !== "processing") return body; // completed or failed
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error(`job ${jobId} still processing: route it to a person`);
}
Jobs typically finish in 20–60 seconds, so poll every 2–5 seconds and treat anything past a few minutes as stuck. Job lookups are limited to 300 a minute per key, so with dozens of jobs in flight, let webhooks do the work and poll only the stragglers. Copy finished images to your own storage, because result URLs are subject to retention limits.
Step 4: errors the agent must branch on. Every non-2xx response is { "error": { "code", "message", "doc_url" } }. Branch on code, never on message. These are the codes an autonomous run will meet (the error reference has them all):
| Code (status) and meaning | What the run should do |
|---|---|
invalid_tool (400): a slug not in GET /v1/tools |
Refresh the tool list; never repeat the call |
invalid_request (400): a missing or out-of-range option |
Fix options in code, not by letting the agent guess |
invalid_image, image_fetch_failed (400): a bad or unreachable source |
Flag the photo and check the URL |
webhook_url_rejected (400), invalid_api_key or key_revoked (401) |
Stop: a configuration or key problem for a person |
insufficient_credits (402) |
Stop and alert a person; buying credits is a human decision |
idempotency_conflict (409): same key, different body |
Stop and fix the key scheme; never retry with a fresh key |
payload_too_large (413) |
Send image_url instead of base64 |
rate_limited (429) |
Wait the Retry-After seconds, then continue |
internal_error (500) |
Retry with the same Idempotency-Key |
Job status: "failed", credits refunded |
Retry once under a new key, such as …-retry-1, because the old key hands back the same failed job; if it fails again, route the photo to a person |
Without an explicit branch for each of these, an agent retries blindly and burns credits.
Why Agents Need Deterministic Tools, Not Chat Interfaces
The uncomfortable truth of agent-driven media: the bottleneck is not model intelligence, it is tool determinism. OWASP's GenAI Security Project names a related risk, "Excessive Agency", and traces it to excessive functionality, permissions or autonomy. The properties that keep an interface agent-friendly are unglamorous:
- Idempotency, so a retry is free rather than billable.
- Stable machine-readable error codes, so failure handling is a branch, not a guess.
- A discovery endpoint and strict option validation, so the agent checks rather than assumes. Where a provider is lenient, as ours is outside staging, validate in your own code.
- Signed push notifications with a polling fallback, so completion does not depend on the agent staying awake.
- Cost in the response, a balance endpoint and a published failure policy, so spending is observable per action and a failed render's cost is known in advance.
A chat window or point-and-click UI offers an agent almost none of these. That is why "the agent will just use our web app" demos well and operates badly: every UI change breaks the run, nothing is idempotent, and a failure looks like a screenshot rather than a code.
The Failure Modes Nobody Budgets For
Prompt injection through your own inbox. A property agent reads emails, PDFs and portal listings written by strangers. In Gray Swan's external testing, reported by The Decoder, attackers with 15 attempts per scenario compromised GPT-6 Astra at least once in 8.5% of scenarios (GPT-5.6 Sol: 27%; Claude Opus 5: 4.8%). No model tested was immune, so never give the same agent both untrusted input and unsupervised authority to publish, pay or contract.
The agent's account of its own work. On 28 September OpenAI cancelled the release of GPT-6.1 Astra. Its head of safety systems said in a statement to Al Jazeera that the model missed the bar for "scope and authorization, and how it communicates back to the user about the type of work it's done". OpenAI's chief scientist has also called chain-of-thought monitoring "fragile". Treat an agent's summary ("all 24 photos staged and published") as a claim, and reconcile it against job objects, your CRM and your own logs.
At-least-once webhook delivery. A handler that times out after doing its work gets the event again, so de-duplicate on job_id and keep handlers idempotent. With up to five attempts over roughly 36 minutes, the first delivery is not necessarily the only one.
No ordering guarantees. Do not assume a webhook arrives after your own POST has returned, or that job A's callback precedes job B's. Write state machines that tolerate arrival in any order.
Cost runaway. Two meters run: the model's tokens and the images. Rate limits are a brake, not a budget: at 60 job creations a minute, a runaway loop could submit 600 jobs in ten minutes, about $150 at the smallest API pack's $0.25 per image. Idempotency keys stop replays, not an agent that keeps submitting new work. Cap spend per run in your code, check the balance first, and alert on unusual job-creation rates.
Silent structural drift. The job says completed, but a window moved. Generative models, ours included, can change things you did not ask them to change, and only a verification step catches it: a person, or an agent that flags differences for a person to judge.
Disclosure that nobody applied. When an agent edits at 4am, only code remembers the rules. In California, Business and Professions Code section 10140.8 (AB 723) has required licensees since 1 January 2026 to disclose digitally altered images in real estate advertising and make the original available. AB 2025, signed in September 2026, extends a similar rule to rental ads from 1 January 2027, covering housing providers as well as licensees and fully AI-generated images. The Roomagen API returns the edited image only, with no disclosure label, so labeling and keeping originals belong in your pipeline; our AB 723 and MLS rules guide has the details.
What Still Belongs to a Human
California's Department of Real Estate is explicit: if an AI tool produces inaccurate information or misleading advertising, "responsibility under current law rests with the licensee and their responsible broker, not the technology provider." Its March 2026 advisory asks licensees to treat AI "as a support tool rather than an independent decision-maker" and to approve AI output before relying on it. The same split works for hotels, retailers and design studios: automate the work, keep the judgement.
| Action | Who does it |
|---|---|
| Read listings, photos and the style guide | The agent alone |
| Submit render jobs within the per-run cap | The agent alone; the cap lives in your code |
| Flag structural drift or a doubtful edit | The agent flags; a person decides |
| Publish an altered image to a portal, MLS or listing site | A person approves, with the disclosure and the original |
| Answer a seller, landlord or guest about how the property was shown | A person |
| Raise the spend cap or buy credits | A person |
| Delete original photos | Nobody while the listing is live |
The human rows will not move soon. Whether an edited photo fairly represents a property carries legal and ethical weight; an unhappy seller needs a conversation, not a retry; and a spend cap the agent cannot change is the cheapest insurance in this architecture.
The Agent-Readiness Checklist for Proptech Teams
Score your own stack. Items 1–8 are blockers: if any is missing, fix the integration surface before an agent runs unattended, because a smarter model will not compensate for a stack that cannot be safely automated.
Before any unattended run
- Every system in the pipeline has an API, or you accept computer use as slower, costlier and more fragile.
- Writes are idempotent, with keys derived from your own records.
- The agent gets narrow tools with enumerated options and never holds an API key.
- Failures branch on error codes, with a stop list: no credits, bad keys, idempotency conflicts, rejected webhook URLs.
- Webhooks are verified over raw bytes with a constant-time comparison, de-duplicated on job ID, tolerant of any arrival order and backed by a poller.
- Spend is capped outside the agent and checked against the live balance before each run.
- Untrusted inputs are isolated from any tool that can publish, pay or contract.
- A person approves before anything goes public.
Before you scale
- Disclosure and original-image retention are enforced in code, not left to habit.
- An audit trail links every published image to its job, its source photo and the agent run that requested it.
- Results are copied to your own storage; a provider's result URL is not an archive.
- A documented stop condition says what halts a run and wakes a person.
The Bottom Line
The Astra era does not mean models will make your listing photos. It means models will operate the tools that make them, which puts the pressure on the tools rather than the intelligence. September showed both sides: agents got better at operating software, and OpenAI held back GPT-6.1 Astra partly over how it reported its own work.
The teams that benefit will run a media stack that is API-first, idempotent, signed, observable and capped, with people holding the approvals that carry legal weight. If you are wiring an agent to an image pipeline, the API quickstart walks through the first request, and the API overview covers pricing, from 50 free images on your first key to packs from 500 images for $125.
Model capabilities, benchmark scores and prices were checked against the sources below on 3 October 2026. API request shapes reflect Roomagen API v1; check the documentation for the current specification.
Ready to transform your listings?
Try Roomagen's AI virtual staging for free. Upload your first photo and see the result, usually in under a minute.
Start FreeSources & References
- 1.OpenAI – API pricing (GPT-6 Astra, GPT-6.1 Sol)
- 2.AWS – Amazon Bedrock model card: OpenAI GPT-6 Astra (input and output modalities)
- 3.The Decoder – GPT-6 Astra is the first model making OpenAI willing to declare the "AGI era" (3 Sep 2026, updated 8 Sep)
- 4.The Decoder – OpenAI's GPT-6 Astra hallucinates less but remains vulnerable to hidden prompt injections (4 Sep 2026)
- 5.The Decoder – OpenAI calls Astra its most dangerous model yet: watching what it does is only getting harder (2 Sep 2026)
- 6.Al Jazeera – OpenAI cancels release of AI model GPT-6.1 Astra, citing safety concerns (29 Sep 2026)
- 7.Google DeepMind – Project Astra
- 8.OWASP GenAI Security Project – LLM06:2025 Excessive Agency
- 9.California Department of Real Estate – Artificial Intelligence in California Real Estate: advisory for licensees (17 Mar 2026)
- 10.California Apartment Association – New law will require disclosures for digitally altered rental ads (AB 2025, 29 Sep 2026)
Frequently Asked Questions
Written by
Roomagen Team
The Roomagen team creates in-depth guides about AI virtual staging, real estate photography, and property marketing strategies to help agents and professionals stay ahead.






