{"openapi":"3.1.0","info":{"title":"ListOnce API","version":"1.0.0","summary":"Enter a listing once; read the public feed; hear about changes.","description":"Member brokerages enter and change listings. Licensees read the RESO feed. Both can subscribe to signed webhooks. Guides: https://listonce.io/developers"},"servers":[{"url":"https://listonce.io","description":"One host for sandbox and live; the key decides."}],"tags":[{"name":"Listings","description":"Enter, change and read listings."},{"name":"RESO feed","description":"What licensees may receive."},{"name":"RESO Add/Edit","description":"Enter and change listings in RESO Data Dictionary names."},{"name":"Photos","description":"Add, order and remove a listing's photos."},{"name":"Webhooks","description":"Signed events about listing changes."},{"name":"Keys","description":"Rotate an API key without downtime."}],"security":[{"apiKey":[]}],"paths":{"/api/v1/listings":{"post":{"operationId":"createListing","summary":"Enter a listing once","description":"Member brokerages only. The caller's organization becomes the listing brokerage and owner. The listing is planned to every destination in its market under the seller's visibility choice and each MLS's current rules, and the history starts with three fingerprinted lines. A listing at the address of another brokerage's active listing is entered and flagged: both owners get a history line (which never names the other brokerage or listing) and listing.conflict, and the pair shows under /api/v1/conflicts until the platform operator decides it.","tags":["Listings"],"security":[{"apiKey":["listings:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Repeats with the same key and body replay the first response for 24 hours; the same key with a different body is refused.","schema":{"type":"string","pattern":"^[\\x21-\\x7E]{1,200}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListingCreate"},"examples":{"membersOnly":{"summary":"Members only","value":{"street":"88 Cedar Bluff Dr","city":"Austin","state":"TX","zip":"78704","price":625000,"beds":3,"baths":2.5,"sqft":1960,"lotAcres":0.18,"yearBuilt":2004,"propertyType":"Single Family","remarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","agent":"Rowan Ellis","seller":"A. and T. Monroe","visibility":"members_only","listingAgreementAt":"2026-10-26"}},"comingSoon":{"summary":"Coming soon","value":{"street":"301 Juniper Hollow","city":"Austin","state":"TX","zip":"78745","price":625000,"beds":3,"baths":2.5,"sqft":1960,"lotAcres":0.18,"yearBuilt":2004,"propertyType":"Single Family","remarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","agent":"Rowan Ellis","seller":"A. and T. Monroe","visibility":"coming_soon","listingAgreementAt":"2026-10-26","goLiveDate":"2026-11-09"}}}}}},"responses":{"201":{"description":"Created. The owner's view of the listing.","headers":{"Idempotent-Replayed":{"description":"`true` when this response is a replay of an earlier request with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Listing"},"example":{"street":"88 Cedar Bluff Dr","city":"Austin","state":"TX","zip":"78704","price":625000,"beds":3,"baths":2.5,"sqft":1960,"lotAcres":0.18,"yearBuilt":2004,"propertyType":"Single Family","remarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","agent":"Rowan Ellis","seller":"A. and T. Monroe","visibility":"members_only","listingAgreementAt":"2026-10-26","id":"OL-RCGZQ4","addressKey":"88|CEDAR BLUFF DR||AUSTIN|TX|78704","brokerage":"Harbor & Pine Realty","source":"api","status":"Active","returns":{},"photos":[],"sellerConsentAt":"2026-10-26T15:04:12.318Z","createdAt":"2026-10-26T15:04:12.318Z","updatedAt":"2026-10-26T15:04:12.318Z","tint":0,"deliveries":[{"destId":"mls-austin","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-a","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-b","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-c","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"net-members","state":"delivered","at":"2026-10-26T15:04:12.318Z"},{"destId":"data-appraisal","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"data-records","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"}],"history":[{"at":"2026-10-26T15:04:12.318Z","who":"Rowan Ellis","what":"Seller chose members only","hash":"0350a77c66e2d3"},{"at":"2026-10-26T15:04:12.318Z","who":"Rowan Ellis","what":"Listing entered once","hash":"1cde064c84ab14"},{"at":"2026-10-26T15:04:12.318Z","who":"ListOnce","what":"Sent to 1 of 7 destinations","hash":"1d54774e9f1ec6"}],"historyIntact":true,"lateDays":0,"remarkFlags":[]}}}},"400":{"description":"A field failed validation, a field is unknown, or the body is not a JSON object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"zip must be a 5 digit ZIP"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks listings:write, or its organization is not a member brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"Only member brokerages enter listings"}}}}},"409":{"description":"The brokerage already has an active listing (Coming Soon, Active or Pending) at this address: existingKey names it. Update that listing, or withdraw it before listing again. Or a request with this Idempotency-Key is still running.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"409","message":"OL-RCGZQ4 is already an active listing of this brokerage at this address; update it, or withdraw it before listing again","existingKey":"OL-RCGZQ4"}}}}},"413":{"description":"Body over 16,384 bytes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"413","message":"Body over 16384 bytes"}}}}},"422":{"description":"This Idempotency-Key was used for a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"422","message":"This Idempotency-Key was used for a different request"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/listings/{key}":{"get":{"operationId":"getListing","summary":"Read a listing","description":"The owner (with listings:read) gets the full listing with its deliveries and history. Another member brokerage with listings:read gets a members only listing as its own marked copy (an alias for the key and photo URLs issued to it), and every read is logged. Any other key with feed:read gets the RESO record, and only while the listing may be publicly marketed: members only and coming soon listings answer 404.","tags":["Listings"],"security":[{"apiKey":["listings:read"]},{"apiKey":["feed:read"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}}],"responses":{"200":{"description":"The owner's view, or the RESO record for a feed reader.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Listing"},{"$ref":"#/components/schemas/Property"},{"$ref":"#/components/schemas/MemberCopy"}]},"example":{"@odata.context":"https://listonce.io/api/reso/$metadata#Property/$entity","ListingKey":"OL-4K7Q2M","OriginatingSystemName":"ListOnce","StandardStatus":"Active","ListPrice":589000,"ClosePrice":null,"UnparsedAddress":"1418 Larkspur Way, Austin, TX 78745","City":"Austin","StateOrProvince":"TX","PostalCode":"78745","PropertyType":"Residential","PropertySubType":"Single Family Residence","BedroomsTotal":3,"BathroomsTotalInteger":2,"BathroomsFull":2,"BathroomsHalf":0,"LivingArea":1840,"LivingAreaUnits":"Square Feet","LotSizeAcres":0.21,"YearBuilt":1998,"PublicRemarks":"Shaded corner lot, updated kitchen, two living areas and a deep backyard with mature oaks.","ListAgentFullName":"Dana Whitfield","ListOfficeName":"Harbor & Pine Realty","ListingContractDate":"2026-10-24","OnMarketDate":"2026-10-24","ModificationTimestamp":"2026-10-24T21:03:00.000Z","LO_SellerVisibilityChoice":"public","LO_SellerChoiceRecordedAt":"2026-10-24T10:20:00.000Z"}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:read or feed:read scope"}}}}},"404":{"description":"No such listing, or not one this key may read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No listing OL-4K7Q2M this key may read"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}},"patch":{"operationId":"updateListing","summary":"Change a listing","description":"Owner only. Send just the fields that change; null clears lotAcres or yearBuilt. A new visibility is a new seller choice: the choice time resets, and switching to or from coming soon moves the status between Coming Soon and Active. soldPrice is allowed only on a Closed listing; leaving Closed drops it. resend true clears MLS send backs and resends to every destination. Every destination is re-planned; one keeps its time unless its outcome changed.","tags":["Listings"],"security":[{"apiKey":["listings:write"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListingPatch"},"examples":{"priceAndStatus":{"summary":"Price cut and under contract","value":{"price":615000,"status":"Pending"}},"resend":{"summary":"Resend everywhere","value":{"resend":true}}}}}},"responses":{"200":{"description":"The owner's view after the change.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Listing"},"example":{"street":"88 Cedar Bluff Dr","city":"Austin","state":"TX","zip":"78704","price":615000,"beds":3,"baths":2.5,"sqft":1960,"lotAcres":0.18,"yearBuilt":2004,"propertyType":"Single Family","remarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","agent":"Rowan Ellis","seller":"A. and T. Monroe","visibility":"members_only","listingAgreementAt":"2026-10-26","id":"OL-RCGZQ4","addressKey":"88|CEDAR BLUFF DR||AUSTIN|TX|78704","brokerage":"Harbor & Pine Realty","source":"api","status":"Pending","returns":{},"photos":[],"sellerConsentAt":"2026-10-26T15:04:12.318Z","createdAt":"2026-10-26T15:04:12.318Z","updatedAt":"2026-10-26T16:40:05.902Z","tint":0,"deliveries":[{"destId":"mls-austin","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-a","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-b","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-c","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"net-members","state":"delivered","at":"2026-10-26T16:40:05.902Z","note":"Shown as pending"},{"destId":"data-appraisal","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"data-records","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"}],"history":[{"at":"2026-10-26T15:04:12.318Z","who":"Rowan Ellis","what":"Seller chose members only","hash":"0350a77c66e2d3"},{"at":"2026-10-26T15:04:12.318Z","who":"Rowan Ellis","what":"Listing entered once","hash":"1cde064c84ab14"},{"at":"2026-10-26T15:04:12.318Z","who":"ListOnce","what":"Sent to 1 of 7 destinations","hash":"1d54774e9f1ec6"},{"at":"2026-10-26T16:40:05.902Z","who":"Harbor & Pine Realty","what":"Price changed to $615,000; Status changed to Pending","hash":"13d47d05eda81d"},{"at":"2026-10-26T16:40:05.902Z","who":"ListOnce","what":"Sent to 1 of 7 destinations","hash":"1b9856cf24d71e"}],"historyIntact":true,"lateDays":0,"remarkFlags":[]}}}},"400":{"description":"A field failed validation, a cross field rule failed, the body was empty, or nothing would change.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"Nothing changed"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:write scope"}}}}},"404":{"description":"No such listing owned by this key's brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No listing OL-4K7Q2M owned by this key's brokerage"}}}}},"409":{"description":"The brokerage already has an active listing (Coming Soon, Active or Pending) at this address: existingKey names it. Update that listing, or withdraw it before listing again. Or the listing changed while this request ran: read it again and retry. Checked when the address changes or the listing comes back to market.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"409","message":"OL-RCGZQ4 is already an active listing of this brokerage at this address; update it, or withdraw it before listing again","existingKey":"OL-RCGZQ4"}}}}},"413":{"description":"Body over 16,384 bytes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"413","message":"Body over 16384 bytes"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/listings/{key}/deliveries":{"get":{"operationId":"listDeliveries","summary":"Where a listing is live","description":"Owner only: one line per destination in the listing's market with its outcome and any note.","tags":["Listings"],"security":[{"apiKey":["listings:read"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}}],"responses":{"200":{"description":"Deliveries, sorted by destination id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryList"},"example":{"listingKey":"OL-4K7Q2M","value":[{"destId":"mls-austin","state":"delivered","at":"2026-10-24T11:02:00.000Z","destination":"Demo MLS Austin","kind":"mls"},{"destId":"net-members","state":"delivered","at":"2026-10-24T11:02:00.000Z","destination":"Member brokerages","kind":"network"},{"destId":"portal-a","state":"delivered","at":"2026-10-24T11:02:00.000Z","destination":"Demo Portal A","kind":"portal"}]}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:read scope"}}}}},"404":{"description":"No such listing owned by this key's brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No listing OL-4K7Q2M this key may read"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/listings/{key}/media/uploads":{"post":{"operationId":"createMediaUpload","summary":"Start a photo upload","description":"Owner only, no body. Answers a one time URL: PUT the photo there as the raw body with its Content-Type (image/jpeg, image/png or image/webp, at most 8 MB), within two hours, then finish with POST /media and the uploadId. A listing holds at most 25 photos.","tags":["Photos"],"security":[{"apiKey":["listings:write"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}}],"responses":{"201":{"description":"Where to PUT the photo.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUpload"},"example":{"uploadId":"5b0c1f9e-2d4a-4c1e-9a77-1f3e2b8d6c40","uploadUrl":"https://storage.example.com/object/upload/sign/listing-photos/uploads/OL-4K7Q2M.5b0c1f9e-2d4a-4c1e-9a77-1f3e2b8d6c40?token=eyJhbGciOi","method":"PUT","expiresAt":"2026-10-26T17:20:41.000Z","maxBytes":8388608,"contentTypes":["image/jpeg","image/png","image/webp"]}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:write scope"}}}}},"404":{"description":"No such listing owned by this key's brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No listing OL-4K7Q2M owned by this brokerage"}}}}},"409":{"description":"The listing already has 25 photos.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"409","message":"A listing holds at most 25 photos"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/listings/{key}/media":{"get":{"operationId":"listMedia","summary":"A listing's photos","description":"Owner only. The photos in order; the first is the preferred one. MediaURL is a signed link on this host that lasts about 12 hours: store the photo, not the link.","tags":["Photos"],"security":[{"apiKey":["listings:read"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}}],"responses":{"200":{"description":"Photos, in order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaList"},"example":{"listingKey":"OL-4K7Q2M","value":[{"MediaKey":"OLP-7RQ2KD9XWM","ResourceRecordKey":"OL-4K7Q2M","ResourceName":"Property","MediaCategory":"Photo","MediaURL":"https://listonce.io/m/OLP-7RQ2KD9XWM.jpg?a=o&e=1793095200&s=Jp2c1v9yQkXo3H7bTn0aLw5rUe8sDf4gZi6mCxVhKqY","Order":0,"ImageWidth":2560,"ImageHeight":1707,"PreferredPhotoYN":true,"ModificationTimestamp":"2026-10-26T15:20:41.000Z"},{"MediaKey":"OLP-C4HNV8TZ3P","ResourceRecordKey":"OL-4K7Q2M","ResourceName":"Property","MediaCategory":"Photo","MediaURL":"https://listonce.io/m/OLP-C4HNV8TZ3P.jpg?a=o&e=1793095200&s=Jp2c1v9yQkXo3H7bTn0aLw5rUe8sDf4gZi6mCxVhKqY","Order":1,"ImageWidth":2560,"ImageHeight":1707,"PreferredPhotoYN":false,"ModificationTimestamp":"2026-10-26T15:20:41.000Z"}]}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:read scope"}}}}},"404":{"description":"No such listing owned by this key's brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No listing OL-4K7Q2M owned by this brokerage"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}},"post":{"operationId":"addMedia","summary":"Finish a photo upload","description":"Owner only. Checks the uploaded file is the JPEG, PNG or WebP its first bytes say, turns it upright, scales it to at most 2560 pixels on the long side and stores it as a JPEG, which drops every metadata block (GPS location included). It becomes the last photo, or the preferred one if it is the first. Adds a history line and sends listing.updated. Finishing the same uploadId again answers the same photo.","tags":["Photos"],"security":[{"apiKey":["listings:write"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAdd"},"example":{"uploadId":"5b0c1f9e-2d4a-4c1e-9a77-1f3e2b8d6c40"}}}},"responses":{"201":{"description":"The photo.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Media"},"example":{"MediaKey":"OLP-C4HNV8TZ3P","ResourceRecordKey":"OL-4K7Q2M","ResourceName":"Property","MediaCategory":"Photo","MediaURL":"https://listonce.io/m/OLP-C4HNV8TZ3P.jpg?a=o&e=1793095200&s=Jp2c1v9yQkXo3H7bTn0aLw5rUe8sDf4gZi6mCxVhKqY","Order":1,"ImageWidth":2560,"ImageHeight":1707,"PreferredPhotoYN":false,"ModificationTimestamp":"2026-10-26T15:20:41.000Z"}}}},"400":{"description":"Unknown field, or uploadId is not an upload id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"uploadId must be the id the upload step gave"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:write scope"}}}}},"404":{"description":"No such listing owned by this key's brokerage, or nothing was PUT to the upload URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No file at that upload yet: PUT the photo to the uploadUrl first, within two hours"}}}}},"409":{"description":"The listing has 25 photos, or it changed while this request ran.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"409","message":"A listing holds at most 25 photos"}}}}},"413":{"description":"The body is over 16,384 bytes, or the photo over 8 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"413","message":"A photo is at most 8 MB"}}}}},"415":{"description":"The file is not a JPEG, PNG or WebP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"415","message":"A photo must be a JPEG, PNG or WebP file"}}}}},"422":{"description":"The file is damaged or over 50 megapixels.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"422","message":"The photo is damaged and cannot be read"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}},"patch":{"operationId":"reorderMedia","summary":"Reorder photos","description":"Owner only. order lists every MediaKey of the listing once; the first becomes the preferred photo. Adds a history line and sends listing.updated.","tags":["Photos"],"security":[{"apiKey":["listings:write"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaOrder"},"example":{"order":["OLP-C4HNV8TZ3P","OLP-7RQ2KD9XWM"]}}}},"responses":{"200":{"description":"The photos in their new order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaList"},"example":{"listingKey":"OL-4K7Q2M","value":[{"MediaKey":"OLP-C4HNV8TZ3P","ResourceRecordKey":"OL-4K7Q2M","ResourceName":"Property","MediaCategory":"Photo","MediaURL":"https://listonce.io/m/OLP-C4HNV8TZ3P.jpg?a=o&e=1793095200&s=Jp2c1v9yQkXo3H7bTn0aLw5rUe8sDf4gZi6mCxVhKqY","Order":0,"ImageWidth":2560,"ImageHeight":1707,"PreferredPhotoYN":true,"ModificationTimestamp":"2026-10-26T15:20:41.000Z"},{"MediaKey":"OLP-7RQ2KD9XWM","ResourceRecordKey":"OL-4K7Q2M","ResourceName":"Property","MediaCategory":"Photo","MediaURL":"https://listonce.io/m/OLP-7RQ2KD9XWM.jpg?a=o&e=1793095200&s=Jp2c1v9yQkXo3H7bTn0aLw5rUe8sDf4gZi6mCxVhKqY","Order":1,"ImageWidth":2560,"ImageHeight":1707,"PreferredPhotoYN":false,"ModificationTimestamp":"2026-10-26T15:20:41.000Z"}]}}}},"400":{"description":"order is not every MediaKey of the listing once, or nothing changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"order must list each of the listing's 2 MediaKeys once"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:write scope"}}}}},"404":{"description":"No such listing owned by this key's brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No listing OL-4K7Q2M owned by this brokerage"}}}}},"409":{"description":"The listing changed while this request ran. Retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"409","message":"OL-4K7Q2M changed while this request ran; read it again and retry"}}}}},"413":{"description":"Body over 16,384 bytes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"413","message":"Body over 16384 bytes"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/listings/{key}/media/{mediaKey}":{"delete":{"operationId":"deleteMedia","summary":"Remove a photo","description":"Owner only. Deletes the stored file; the next photo moves up, and if this was the preferred one, the new first photo is. Adds a history line and sends listing.updated.","tags":["Photos"],"security":[{"apiKey":["listings:write"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}},{"name":"mediaKey","in":"path","required":true,"description":"The photo's MediaKey.","schema":{"type":"string","pattern":"^OLP-[A-HJ-NP-Z2-9]{10}$","examples":["OLP-7RQ2KD9XWM"]}}],"responses":{"204":{"description":"Removed."},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:write scope"}}}}},"404":{"description":"No such listing owned by this key's brokerage, or no such photo on it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No photo OLP-7RQ2KD9XWM on OL-4K7Q2M"}}}}},"409":{"description":"The listing changed while this request ran. Retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"409","message":"OL-4K7Q2M changed while this request ran; read it again and retry"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/export":{"get":{"operationId":"exportListings","summary":"Export everything your brokerage owns","description":"Member brokerages only. Every listing the caller's brokerage owns, as the owner sees them: deliveries and whole history. Sorted by key, at most 50 a page; follow nextLink until it is absent. Signed-in admins can download the same as one JSON lines file from Settings.","tags":["Listings"],"security":[{"apiKey":["listings:read"]}],"parameters":[{"name":"after","in":"query","description":"Start after this listing key. nextLink sets it.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-RCGZQ3"]}}],"responses":{"200":{"description":"One page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportPage"},"example":{"organization":"Harbor & Pine Realty","exportedAt":"2026-10-26T16:40:05.902Z","value":[{"street":"88 Cedar Bluff Dr","city":"Austin","state":"TX","zip":"78704","price":625000,"beds":3,"baths":2.5,"sqft":1960,"lotAcres":0.18,"yearBuilt":2004,"propertyType":"Single Family","remarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","agent":"Rowan Ellis","seller":"A. and T. Monroe","visibility":"members_only","listingAgreementAt":"2026-10-26","id":"OL-RCGZQ4","addressKey":"88|CEDAR BLUFF DR||AUSTIN|TX|78704","brokerage":"Harbor & Pine Realty","source":"api","status":"Active","returns":{},"photos":[],"sellerConsentAt":"2026-10-26T15:04:12.318Z","createdAt":"2026-10-26T15:04:12.318Z","updatedAt":"2026-10-26T15:04:12.318Z","tint":0,"deliveries":[{"destId":"mls-austin","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-a","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-b","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"portal-c","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"net-members","state":"delivered","at":"2026-10-26T15:04:12.318Z"},{"destId":"data-appraisal","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"},{"destId":"data-records","state":"held","note":"Seller chose members only","at":"2026-10-26T15:04:12.318Z"}],"history":[{"at":"2026-10-26T15:04:12.318Z","who":"Rowan Ellis","what":"Seller chose members only","hash":"0350a77c66e2d3"},{"at":"2026-10-26T15:04:12.318Z","who":"Rowan Ellis","what":"Listing entered once","hash":"1cde064c84ab14"},{"at":"2026-10-26T15:04:12.318Z","who":"ListOnce","what":"Sent to 1 of 7 destinations","hash":"1d54774e9f1ec6"}],"historyIntact":true,"lateDays":0,"remarkFlags":[]}],"nextLink":"https://listonce.io/api/v1/export?after=OL-RCGZQ4"}}}},"400":{"description":"after is not a listing key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"after must be a listing key"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks listings:read, or its organization is not a member brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"Export is for member brokerages"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/conflicts":{"get":{"operationId":"listConflicts","summary":"Same address as another brokerage","description":"Member brokerages only. Each of the caller's listings that was active at the same canonical address as another brokerage's active listing, open ones first. Addresses are compared after normalizing (St and Street, Apt and #, case, spacing). Of the other listing you see only its key, brokerage and status. The platform operator decides each one: a co-listing, a wrong address (naming which listing) or resolved; both owners get a history line and listing.conflict.","tags":["Listings"],"security":[{"apiKey":["listings:read"]}],"parameters":[{"name":"listing","in":"query","description":"Only this listing's.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-RCGZQ4"]}},{"name":"status","in":"query","description":"open for undecided ones only; all (the default) for every one.","schema":{"type":"string","enum":["open","all"]}}],"responses":{"200":{"description":"Open first, then newest. At most 200.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConflictList"},"example":{"value":[{"id":"4f1c2a9e-5b7d-4e3a-9c21-6d8e0f4b2a17","status":"open","listingKey":"OL-RCGZQ4","other":{"listingKey":"OL-7MWX2D","brokerage":"Bluebird Realty Co","status":"Active"},"wrongListing":null,"createdAt":"2026-10-26T16:40:05.902Z","decidedAt":null}]}}}},"400":{"description":"An unknown parameter, a listing that is not a key, or a status other than open or all.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"status must be open or all"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks listings:read, or its organization is not a member brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"Only member brokerages have listings"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/webhooks":{"post":{"operationId":"createWebhook","summary":"Subscribe to listing changes","description":"The URL must be https on the standard port, carry no credentials, and resolve only to public addresses (checked again at every send). At most 10 per organization. The signing secret is in this response only.","tags":["Webhooks"],"security":[{"apiKey":["webhooks:manage"]}],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Repeats with the same key and body replay the first response for 24 hours; the same key with a different body is refused.","schema":{"type":"string","pattern":"^[\\x21-\\x7E]{1,200}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreate"},"example":{"url":"https://example.com/hooks/listings","events":["listing.updated"]}}}},"responses":{"201":{"description":"Created. Store the secret now; it is not shown again.","headers":{"Idempotent-Replayed":{"description":"`true` when this response is a replay of an earlier request with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"},"example":{"id":"a7a332fd-bef7-4c6a-a362-9e9a3467e2d8","url":"https://example.com/hooks/listings","events":["listing.updated"],"active":true,"createdAt":"2026-10-26T15:10:03.520883+00:00","secret":"whsec_4214177e6e99d1059b387b23bd89a068204cbd7b35b21692"}}}},"400":{"description":"Unknown field, bad events, or a URL that is not https, not public or does not resolve.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"url must point at a public address"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the webhooks:manage scope"}}}}},"409":{"description":"The organization already has 10 webhooks, or a request with this Idempotency-Key is still running.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"409","message":"At most 10 webhooks per organization"}}}}},"413":{"description":"Body over 16,384 bytes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"413","message":"Body over 16384 bytes"}}}}},"422":{"description":"This Idempotency-Key was used for a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"422","message":"This Idempotency-Key was used for a different request"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}},"get":{"operationId":"listWebhooks","summary":"Your subscriptions","description":"Every webhook of the key's organization, oldest first, with its most recent delivery.","tags":["Webhooks"],"security":[{"apiKey":["webhooks:manage"]}],"responses":{"200":{"description":"Webhooks.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookList"},"example":{"value":[{"id":"a7a332fd-bef7-4c6a-a362-9e9a3467e2d8","url":"https://example.com/hooks/listings","events":["listing.updated"],"active":true,"createdAt":"2026-10-26T15:10:03.520883+00:00","lastDelivery":{"status":"sent","code":200,"attempts":1,"at":"2026-10-26T16:40:06.114771+00:00"}}]}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the webhooks:manage scope"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/webhooks/{id}":{"delete":{"operationId":"deleteWebhook","summary":"Unsubscribe","description":"Deletes the webhook and its delivery records.","tags":["Webhooks"],"security":[{"apiKey":["webhooks:manage"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook id. A malformed id answers 404.","schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted."},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the webhooks:manage scope"}}}}},"404":{"description":"No such webhook for this key's organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No such webhook for this key's organization"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/v1/keys/rotate":{"post":{"operationId":"rotateKey","summary":"Rotate this key","description":"Replaces the key that signs the request. The new key (same label, scopes and rate limit) is returned once and works at once; the old key keeps working for 24 hours, then stops. Rotating a key that is already being replaced answers 409, so store the new key before anything else. No body. The published demo key cannot be rotated.","tags":["Keys"],"security":[{"apiKey":["listings:write"]},{"apiKey":["listings:read"]},{"apiKey":["feed:read"]},{"apiKey":["webhooks:manage"]}],"responses":{"201":{"description":"The new key. It is not shown again.","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","description":"The new API key. Shown once; only its hash is kept."},"id":{"type":"string","description":"The new key's id.","format":"uuid"},"prefix":{"type":"string","description":"The visible start of the new key, as Settings lists it."},"previousKeyExpiresAt":{"type":"string","description":"When the key that made this call stops working.","format":"date-time"}},"required":["key","id","prefix","previousKeyExpiresAt"],"additionalProperties":false},"example":{"key":"ol_live_3f9c0d2b7a8e4c1f9d6b5a4e3c2b1a0f9e8d7c6b","id":"9b1c7e3a-4f2d-4c8b-a6e5-1d2c3b4a5f60","prefix":"ol_live_3f9c0d","previousKeyExpiresAt":"2026-10-28T15:10:03.520Z"}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The published demo key, which is shared and cannot be rotated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"The published demo key cannot be rotated"}}}}},"409":{"description":"This key was already rotated; its replacement is the key to use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"409","message":"This key is already being replaced. Use its replacement, or create a new key."}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/reso":{"get":{"operationId":"serviceDocument","summary":"Service document","description":"The OData service document: the entity sets this feed publishes.","tags":["RESO feed"],"security":[{"apiKey":["feed:read"]}],"parameters":[{"name":"key","in":"query","description":"The API key, for a browser link. Prefer the Authorization header: query strings end up in logs.","schema":{"type":"string"}}],"responses":{"200":{"description":"Entity sets.","content":{"application/json":{"schema":{"type":"object","properties":{"@odata.context":{"type":"string","description":"The $metadata document.","format":"uri"},"value":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Entity set."},"kind":{"type":"string","description":"Always EntitySet.","enum":["EntitySet"]},"url":{"type":"string","description":"Relative URL."}},"required":["name","kind","url"],"additionalProperties":false},"description":"Entity sets."}},"required":["@odata.context","value"],"additionalProperties":false},"example":{"@odata.context":"https://listonce.io/api/reso/$metadata","value":[{"name":"Property","kind":"EntitySet","url":"Property"},{"name":"Media","kind":"EntitySet","url":"Media"},{"name":"Lookup","kind":"EntitySet","url":"Lookup"}]}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the feed:read scope"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/reso/$metadata":{"get":{"operationId":"metadata","summary":"Data model","description":"The OData CSDL XML for Property (with its Media navigation property), Media and Lookup, with RESO lookup annotations. Always XML; `$format=json` answers 415.","tags":["RESO feed"],"security":[{"apiKey":["feed:read"]}],"parameters":[{"name":"key","in":"query","description":"The API key, for a browser link. Prefer the Authorization header: query strings end up in logs.","schema":{"type":"string"}}],"responses":{"200":{"description":"application/xml."},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the feed:read scope"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/reso/Lookup":{"get":{"operationId":"lookups","summary":"Lookup values","description":"Every lookup value the feed can send, as the RESO Lookup resource. Takes the same query options as Property.","tags":["RESO feed"],"security":[{"apiKey":["feed:read"]}],"parameters":[{"name":"key","in":"query","description":"The API key, for a browser link. Prefer the Authorization header: query strings end up in logs.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of lookup rows.","content":{"application/json":{"schema":{"type":"object","properties":{"@odata.context":{"type":"string","description":"OData context.","format":"uri"},"@odata.count":{"type":"integer","description":"Rows matching, with $count=true."},"value":{"type":"array","description":"This page.","items":{"type":"object","properties":{"LookupKey":{"type":"string","description":"Name and value."},"LookupName":{"type":"string","description":"The lookup."},"LookupValue":{"type":"string","description":"The value as sent."},"StandardLookupValue":{"type":["string","null"],"description":"The RESO standard value, or null for a local one."},"LegacyODataValue":{"type":["string","null"],"description":"The value as an OData enum name."},"ModificationTimestamp":{"type":"string","description":"When the value last changed.","format":"date-time"}},"required":["LookupKey","LookupName","LookupValue","StandardLookupValue","LegacyODataValue","ModificationTimestamp"],"additionalProperties":false}},"@odata.nextLink":{"type":"string","description":"The next page.","format":"uri"}},"required":["@odata.context","value"],"additionalProperties":false},"example":{"@odata.context":"https://listonce.io/api/reso/$metadata#Lookup","value":[{"LookupKey":"StandardStatus:Active","LookupName":"StandardStatus","LookupValue":"Active","StandardLookupValue":"Active","LegacyODataValue":"Active","ModificationTimestamp":"2026-10-26T00:00:00.000Z"}]}}}},"400":{"description":"A query option the server cannot read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"$filter cannot use Nope; filterable fields are listed in $metadata"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the feed:read scope"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/reso/Property":{"post":{"operationId":"createProperty","summary":"Enter a listing in RESO fields","description":"RESO Web API Add/Edit, for systems that already speak RESO. The same listing, rules and owner as `POST /api/v1/listings`, in Data Dictionary names plus two extensions: LO_SellerVisibilityChoice and LO_SellerName (write only; never in the feed). We assign ListingKey; read only fields (ListingKey, OriginatingSystemName, ListOfficeName, ModificationTimestamp, LO_SellerChoiceRecordedAt) and `@odata.` annotations are ignored, and any other name is refused. Baths: BathroomsFull with BathroomsHalf, or BathroomsTotalInteger alone. StandardStatus may be sent if it matches the seller's choice (Coming Soon for coming_soon, otherwise Active); OnMarketDate is the go live date for coming_soon. Errors carry `target` (Create) and `details` naming each field.","tags":["RESO Add/Edit"],"security":[{"apiKey":["listings:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Repeats with the same key and body replay the first response for 24 hours; the same key with a different body is refused.","schema":{"type":"string","pattern":"^[\\x21-\\x7E]{1,200}$"}},{"name":"Prefer","in":"header","description":"Optional. `return=representation` answers with the record, `return=minimal` with no body; echoed in Preference-Applied. Without it a POST answers 201 with the record and a PATCH 204.","schema":{"type":"string","enum":["return=representation","return=minimal"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyCreate"},"examples":{"membersOnly":{"summary":"Members only","value":{"UnparsedAddress":"88 Cedar Bluff Dr, Austin, TX 78704","City":"Austin","StateOrProvince":"TX","PostalCode":"78704","ListPrice":625000,"BedroomsTotal":3,"BathroomsFull":2,"BathroomsHalf":1,"LivingArea":1960,"LotSizeAcres":0.18,"YearBuilt":2004,"PropertyType":"Residential","PropertySubType":"Single Family Residence","PublicRemarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","ListAgentFullName":"Rowan Ellis","ListingContractDate":"2026-10-26","LO_SellerVisibilityChoice":"members_only","LO_SellerName":"A. and T. Monroe"}},"comingSoon":{"summary":"Coming soon","value":{"UnparsedAddress":"301 Juniper Hollow, Austin, TX 78745","City":"Austin","StateOrProvince":"TX","PostalCode":"78745","ListPrice":625000,"BedroomsTotal":3,"BathroomsFull":2,"BathroomsHalf":1,"LivingArea":1960,"LotSizeAcres":0.18,"YearBuilt":2004,"PropertyType":"Residential","PropertySubType":"Single Family Residence","PublicRemarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","ListAgentFullName":"Rowan Ellis","ListingContractDate":"2026-10-26","LO_SellerVisibilityChoice":"coming_soon","LO_SellerName":"A. and T. Monroe","OnMarketDate":"2026-11-09"}}}}}},"responses":{"201":{"description":"Created. The record as the owner sees it.","headers":{"Location":{"description":"The record's URL: `/api/reso/Property('OL-...')`.","schema":{"type":"string","format":"uri"}},"EntityId":{"description":"The listing key.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$"}},"Idempotent-Replayed":{"description":"`true` when this response is a replay of an earlier request with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyWritten"},"example":{"@odata.context":"https://listonce.io/api/reso/$metadata#Property/$entity","ListingKey":"OL-RCGZQ4","OriginatingSystemName":"ListOnce","StandardStatus":"Active","ListPrice":625000,"ClosePrice":null,"UnparsedAddress":"88 Cedar Bluff Dr, Austin, TX 78704","City":"Austin","StateOrProvince":"TX","PostalCode":"78704","PropertyType":"Residential","PropertySubType":"Single Family Residence","BedroomsTotal":3,"BathroomsTotalInteger":3,"BathroomsFull":2,"BathroomsHalf":1,"LivingArea":1960,"LivingAreaUnits":"Square Feet","LotSizeAcres":0.18,"YearBuilt":2004,"PublicRemarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","ListAgentFullName":"Rowan Ellis","ListOfficeName":"Harbor & Pine Realty","ListingContractDate":"2026-10-26","OnMarketDate":"2026-10-26","ModificationTimestamp":"2026-10-26T15:04:12.318Z","LO_SellerVisibilityChoice":"members_only","LO_SellerChoiceRecordedAt":"2026-10-26T15:04:12.318Z"}}}},"204":{"description":"Created, with `Prefer: return=minimal`.","headers":{"Location":{"description":"The record's URL: `/api/reso/Property('OL-...')`.","schema":{"type":"string","format":"uri"}},"EntityId":{"description":"The listing key.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$"}},"Idempotent-Replayed":{"description":"`true` when this response is a replay of an earlier request with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}}},"400":{"description":"A field failed validation, is missing or is unknown. details names each field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ODataError"},"example":{"error":{"code":"400","message":"Missing: ListAgentFullName","target":"Create","details":[{"code":"400","target":"ListAgentFullName","message":"Missing: ListAgentFullName"}]}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks listings:write, or its organization is not a member brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"Only member brokerages enter listings"}}}}},"409":{"description":"The brokerage already has an active listing (Coming Soon, Active or Pending) at this address: existingKey names it. Update that listing, or withdraw it before listing again. Or a request with this Idempotency-Key is still running.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ODataError"},"example":{"error":{"code":"409","message":"OL-RCGZQ4 is already an active listing of this brokerage at this address; update it, or withdraw it before listing again","existingKey":"OL-RCGZQ4"}}}}},"413":{"description":"Body over 16,384 bytes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"413","message":"Body over 16384 bytes"}}}}},"422":{"description":"This Idempotency-Key was used for a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"422","message":"This Idempotency-Key was used for a different request"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}},"get":{"operationId":"searchProperties","summary":"Search the feed","description":"RESO Web API Core style. Newest change first unless `$orderby` says otherwise, then by key. Members only and coming soon listings are never included. Pages hold at most 50 records; a nextLink follows when the server cut a page short. `Property('OL-4K7Q2M')` fetches one record too.","tags":["RESO feed"],"security":[{"apiKey":["feed:read"]}],"parameters":[{"name":"$top","in":"query","description":"How many records you want. The server sends at most 50 per page.","schema":{"type":"integer","minimum":0}},{"name":"$skip","in":"query","description":"Records to skip, up to 100,000.","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"$filter","in":"query","description":"OData: `eq ne gt ge lt le`, `and or not`, parentheses, `null` with eq and ne. Strings in single quotes, dates as YYYY-MM-DD, timestamps in ISO 8601. Fields: ListingKey, StandardStatus, ListPrice, ClosePrice, City, StateOrProvince, PostalCode, PropertySubType, BedroomsTotal, LivingArea, LotSizeAcres, YearBuilt, ListAgentFullName, ListOfficeName, ListingContractDate, ModificationTimestamp.","schema":{"type":"string","maxLength":2000,"examples":["City eq 'Austin' and StandardStatus eq 'Active'","ListPrice gt 500000 and BedroomsTotal ge 3"]}},{"name":"$select","in":"query","description":"Comma separated fields to return.","schema":{"type":"string","examples":["ListingKey,ListPrice,City"]}},{"name":"$orderby","in":"query","description":"Up to 5 filterable fields, each optionally `asc` or `desc`.","schema":{"type":"string","examples":["ListPrice desc"]}},{"name":"$count","in":"query","description":"`true` adds @odata.count.","schema":{"type":"string","enum":["true","false"]}},{"name":"$expand","in":"query","description":"`Media` adds each record's photos, in order, as a Media array. Nothing else expands.","schema":{"type":"string","enum":["Media"]}},{"name":"key","in":"query","description":"The API key, for a browser link. Prefer the Authorization header: query strings end up in logs.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of RESO records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyPage"},"example":{"@odata.context":"https://listonce.io/api/reso/$metadata#Property","@odata.count":1,"value":[{"ListingKey":"OL-4K7Q2M","OriginatingSystemName":"ListOnce","StandardStatus":"Active","ListPrice":589000,"ClosePrice":null,"UnparsedAddress":"1418 Larkspur Way, Austin, TX 78745","City":"Austin","StateOrProvince":"TX","PostalCode":"78745","PropertyType":"Residential","PropertySubType":"Single Family Residence","BedroomsTotal":3,"BathroomsTotalInteger":2,"BathroomsFull":2,"BathroomsHalf":0,"LivingArea":1840,"LivingAreaUnits":"Square Feet","LotSizeAcres":0.21,"YearBuilt":1998,"PublicRemarks":"Shaded corner lot, updated kitchen, two living areas and a deep backyard with mature oaks.","ListAgentFullName":"Dana Whitfield","ListOfficeName":"Harbor & Pine Realty","ListingContractDate":"2026-10-24","OnMarketDate":"2026-10-24","ModificationTimestamp":"2026-10-24T21:03:00.000Z","LO_SellerVisibilityChoice":"public","LO_SellerChoiceRecordedAt":"2026-10-24T10:20:00.000Z"}]}}}},"400":{"description":"A query option the server cannot read: an unknown field, operator or option.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"$filter cannot use Price; filterable fields are listed in $metadata"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the feed:read scope"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/reso/Property('{key}')":{"patch":{"operationId":"updateProperty","summary":"Change a listing in RESO fields","description":"RESO Web API Add/Edit. Owner only, with the same rules as `PATCH /api/v1/listings/{key}`: send just the fields that change; null clears LotSizeAcres or YearBuilt. OnMarketDate sets the go live date while the listing is Coming Soon and is ignored otherwise. ListAgentFullName, ListingContractDate and LO_SellerName cannot change. A record read from this API can be sent back whole: read only fields are ignored. Also answers at `/api/reso/Property/{key}`. Honors Idempotency-Key.","tags":["RESO Add/Edit"],"security":[{"apiKey":["listings:write"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}},{"name":"Idempotency-Key","in":"header","description":"Optional. Repeats with the same key and body replay the first response for 24 hours; the same key with a different body is refused.","schema":{"type":"string","pattern":"^[\\x21-\\x7E]{1,200}$"}},{"name":"Prefer","in":"header","description":"Optional. `return=representation` answers with the record, `return=minimal` with no body; echoed in Preference-Applied. Without it a POST answers 201 with the record and a PATCH 204.","schema":{"type":"string","enum":["return=representation","return=minimal"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyPatch"},"examples":{"priceAndStatus":{"summary":"Price cut and under contract","value":{"ListPrice":615000,"StandardStatus":"Pending"}},"closed":{"summary":"Closed","value":{"StandardStatus":"Closed","ClosePrice":610000}}}}}},"responses":{"200":{"description":"Changed, with `Prefer: return=representation`: the record as the owner sees it.","headers":{"Location":{"description":"The record's URL: `/api/reso/Property('OL-...')`.","schema":{"type":"string","format":"uri"}},"EntityId":{"description":"The listing key.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$"}},"Idempotent-Replayed":{"description":"`true` when this response is a replay of an earlier request with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyWritten"},"example":{"@odata.context":"https://listonce.io/api/reso/$metadata#Property/$entity","ListingKey":"OL-RCGZQ4","OriginatingSystemName":"ListOnce","StandardStatus":"Pending","ListPrice":615000,"ClosePrice":null,"UnparsedAddress":"88 Cedar Bluff Dr, Austin, TX 78704","City":"Austin","StateOrProvince":"TX","PostalCode":"78704","PropertyType":"Residential","PropertySubType":"Single Family Residence","BedroomsTotal":3,"BathroomsTotalInteger":3,"BathroomsFull":2,"BathroomsHalf":1,"LivingArea":1960,"LivingAreaUnits":"Square Feet","LotSizeAcres":0.18,"YearBuilt":2004,"PublicRemarks":"Quiet street, open kitchen and a covered patio facing the greenbelt.","ListAgentFullName":"Rowan Ellis","ListOfficeName":"Harbor & Pine Realty","ListingContractDate":"2026-10-26","OnMarketDate":"2026-10-26","ModificationTimestamp":"2026-10-26T16:40:05.902Z","LO_SellerVisibilityChoice":"members_only","LO_SellerChoiceRecordedAt":"2026-10-26T15:04:12.318Z"}}}},"204":{"description":"Changed. No body unless `Prefer: return=representation`.","headers":{"Location":{"description":"The record's URL: `/api/reso/Property('OL-...')`.","schema":{"type":"string","format":"uri"}},"EntityId":{"description":"The listing key.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$"}},"Idempotent-Replayed":{"description":"`true` when this response is a replay of an earlier request with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}}},"400":{"description":"A field failed validation or is unknown, a cross field rule failed, or nothing would change. details names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ODataError"},"example":{"error":{"code":"400","message":"ListPrice must be a whole number from 1 to 1000000000","target":"Update","details":[{"code":"400","target":"ListPrice","message":"ListPrice must be a whole number from 1 to 1000000000"}]}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the listings:write scope"}}}}},"404":{"description":"No such listing owned by this key's brokerage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ODataError"},"example":{"error":{"code":"404","message":"No listing OL-4K7Q2M owned by this key's brokerage","target":"Update"}}}}},"409":{"description":"The brokerage already has an active listing (Coming Soon, Active or Pending) at this address: existingKey names it. Update that listing, or withdraw it before listing again. Or the listing changed while this request ran, or a request with this Idempotency-Key is still running.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ODataError"},"example":{"error":{"code":"409","message":"OL-RCGZQ4 is already an active listing of this brokerage at this address; update it, or withdraw it before listing again","existingKey":"OL-RCGZQ4"}}}}},"413":{"description":"Body over 16,384 bytes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"413","message":"Body over 16384 bytes"}}}}},"422":{"description":"This Idempotency-Key was used for a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"422","message":"This Idempotency-Key was used for a different request"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/reso/Property/{key}":{"get":{"operationId":"getProperty","summary":"One listing from the feed","description":"The RESO record, while the listing may be publicly marketed.","tags":["RESO feed"],"security":[{"apiKey":["feed:read"]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The listing key. A key of the wrong shape answers 404, like a missing one.","schema":{"type":"string","pattern":"^OL-[A-Z0-9]{6}$","examples":["OL-4K7Q2M"]}},{"name":"$expand","in":"query","description":"`Media` adds each record's photos, in order, as a Media array. Nothing else expands.","schema":{"type":"string","enum":["Media"]}},{"name":"key","in":"query","description":"The API key, for a browser link. Prefer the Authorization header: query strings end up in logs.","schema":{"type":"string"}}],"responses":{"200":{"description":"The RESO record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Property"},"example":{"@odata.context":"https://listonce.io/api/reso/$metadata#Property/$entity","ListingKey":"OL-4K7Q2M","OriginatingSystemName":"ListOnce","StandardStatus":"Active","ListPrice":589000,"ClosePrice":null,"UnparsedAddress":"1418 Larkspur Way, Austin, TX 78745","City":"Austin","StateOrProvince":"TX","PostalCode":"78745","PropertyType":"Residential","PropertySubType":"Single Family Residence","BedroomsTotal":3,"BathroomsTotalInteger":2,"BathroomsFull":2,"BathroomsHalf":0,"LivingArea":1840,"LivingAreaUnits":"Square Feet","LotSizeAcres":0.21,"YearBuilt":1998,"PublicRemarks":"Shaded corner lot, updated kitchen, two living areas and a deep backyard with mature oaks.","ListAgentFullName":"Dana Whitfield","ListOfficeName":"Harbor & Pine Realty","ListingContractDate":"2026-10-24","OnMarketDate":"2026-10-24","ModificationTimestamp":"2026-10-24T21:03:00.000Z","LO_SellerVisibilityChoice":"public","LO_SellerChoiceRecordedAt":"2026-10-24T10:20:00.000Z"}}}},"400":{"description":"$expand names something other than Media.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"$expand takes Media; nested options are not supported"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the feed:read scope"}}}}},"404":{"description":"Not in the feed: missing, members only or coming soon.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"404","message":"No listing OL-4K7Q2M in the feed"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}},"/api/reso/Media":{"get":{"operationId":"searchMedia","summary":"Photos in the feed","description":"The RESO Media resource: photos of the listings in the feed only, newest change first unless `$orderby` says otherwise, then by MediaKey. Takes the same query options as Property; pages hold at most 100. `Media('OLP-7RQ2KD9XWM')` fetches one. A feed link stops working as soon as its listing leaves the feed. MediaURL is a signed link on this host that lasts about 12 hours: store the photo, not the link.","tags":["RESO feed"],"security":[{"apiKey":["feed:read"]}],"parameters":[{"name":"$filter","in":"query","description":"As on Property. PreferredPhotoYN takes true or false with eq and ne. Fields: MediaKey, ResourceRecordKey, MediaCategory, Order, ImageWidth, ImageHeight, PreferredPhotoYN, ModificationTimestamp.","schema":{"type":"string","maxLength":2000,"examples":["ResourceRecordKey eq 'OL-4K7Q2M'","PreferredPhotoYN eq true and ModificationTimestamp gt 2026-10-01T00:00:00Z"]}},{"name":"key","in":"query","description":"The API key, for a browser link. Prefer the Authorization header: query strings end up in logs.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of Media records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaPage"},"example":{"@odata.context":"https://listonce.io/api/reso/$metadata#Media","value":[{"MediaKey":"OLP-7RQ2KD9XWM","ResourceRecordKey":"OL-4K7Q2M","ResourceName":"Property","MediaCategory":"Photo","MediaURL":"https://listonce.io/m/OLP-7RQ2KD9XWM.jpg?a=p&e=1793095200&s=Jp2c1v9yQkXo3H7bTn0aLw5rUe8sDf4gZi6mCxVhKqY","Order":0,"ImageWidth":2560,"ImageHeight":1707,"PreferredPhotoYN":true,"ModificationTimestamp":"2026-10-26T15:20:41.000Z"},{"MediaKey":"OLP-C4HNV8TZ3P","ResourceRecordKey":"OL-4K7Q2M","ResourceName":"Property","MediaCategory":"Photo","MediaURL":"https://listonce.io/m/OLP-C4HNV8TZ3P.jpg?a=p&e=1793095200&s=Jp2c1v9yQkXo3H7bTn0aLw5rUe8sDf4gZi6mCxVhKqY","Order":1,"ImageWidth":2560,"ImageHeight":1707,"PreferredPhotoYN":false,"ModificationTimestamp":"2026-10-26T15:20:41.000Z"}]}}}},"400":{"description":"A query option the server cannot read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"400","message":"$filter cannot use Url; filterable fields are listed in $metadata"}}}}},"401":{"description":"No key, a malformed key, or a revoked one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"401","message":"Send an API key as a Bearer token"}}}},"headers":{"WWW-Authenticate":{"description":"Always `Bearer realm=\"listonce\"`.","schema":{"type":"string"}}}},"403":{"description":"The key lacks the scope this route needs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"403","message":"This key needs the feed:read scope"}}}}},"429":{"description":"Over this key's requests per minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"429","message":"Over 120 requests a minute for this key"}}}},"headers":{"Retry-After":{"description":"Seconds until the minute window resets.","schema":{"type":"integer"}}}}}}}},"webhooks":{"listing.created":{"post":{"operationId":"listing_created","summary":"A listing was entered","description":"Sent to the owner, and to licensees when the new listing may be publicly marketed.","tags":["Webhooks"],"security":[],"parameters":[{"name":"X-ListOnce-Signature","in":"header","required":true,"description":"`sha256=` then the hex HMAC SHA-256 of `timestamp.body` under the webhook's secret.","schema":{"type":"string","pattern":"^sha256=[0-9a-f]{64}$"}},{"name":"X-ListOnce-Timestamp","in":"header","required":true,"description":"Unix seconds when this attempt was signed. Refuse old ones to stop replays.","schema":{"type":"string","pattern":"^\\d{10}$"}},{"name":"X-ListOnce-Delivery","in":"header","required":true,"description":"Stable across retries; equals the payload id. Dedupe on it.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"},"example":{"id":"OL-4K7Q2M:5:a7a332fd-bef7-4c6a-a362-9e9a3467e2d8","event":"listing.created","listingKey":"OL-4K7Q2M","status":"Active","updatedAt":"2026-10-26T16:40:05.902+00:00"}}}},"responses":{"200":{"description":"Any 2xx within 8 seconds counts as received. Anything else, a redirect or a timeout is retried."}},"x-codeSamples":[{"lang":"javascript","label":"Node","source":"import { createHmac, timingSafeEqual } from \"node:crypto\";\n\n// rawBody: the request body exactly as received, before JSON parsing.\nexport function verify(secret, headers, rawBody, toleranceSeconds = 300) {\n  const timestamp = headers[\"x-listonce-timestamp\"];\n  const signature = headers[\"x-listonce-signature\"] ?? \"\";\n  if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false;\n  const expected = \"sha256=\" + createHmac(\"sha256\", secret).update(`${timestamp}.${rawBody}`).digest(\"hex\");\n  return signature.length === expected.length && timingSafeEqual(Buffer.from(signature), Buffer.from(expected));\n}\n"},{"lang":"python","label":"Python","source":"import hashlib\nimport hmac\nimport time\n\n# raw_body: the request body bytes exactly as received, before JSON parsing.\ndef verify(secret: str, headers, raw_body: bytes, tolerance_seconds: int = 300) -> bool:\n    timestamp = headers.get(\"X-ListOnce-Timestamp\", \"\")\n    signature = headers.get(\"X-ListOnce-Signature\", \"\")\n    if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > tolerance_seconds:\n        return False\n    signed = timestamp.encode() + b\".\" + raw_body\n    expected = \"sha256=\" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, signature)\n"}]}},"listing.updated":{"post":{"operationId":"listing_updated","summary":"A listing changed","description":"Sent on any change, photos included, to the owner, and to licensees when the listing was or now is publicly marketed, so a feed can take it down.","tags":["Webhooks"],"security":[],"parameters":[{"name":"X-ListOnce-Signature","in":"header","required":true,"description":"`sha256=` then the hex HMAC SHA-256 of `timestamp.body` under the webhook's secret.","schema":{"type":"string","pattern":"^sha256=[0-9a-f]{64}$"}},{"name":"X-ListOnce-Timestamp","in":"header","required":true,"description":"Unix seconds when this attempt was signed. Refuse old ones to stop replays.","schema":{"type":"string","pattern":"^\\d{10}$"}},{"name":"X-ListOnce-Delivery","in":"header","required":true,"description":"Stable across retries; equals the payload id. Dedupe on it.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"},"example":{"id":"OL-4K7Q2M:5:a7a332fd-bef7-4c6a-a362-9e9a3467e2d8","event":"listing.updated","listingKey":"OL-4K7Q2M","status":"Pending","updatedAt":"2026-10-26T16:40:05.902+00:00"}}}},"responses":{"200":{"description":"Any 2xx within 8 seconds counts as received. Anything else, a redirect or a timeout is retried."}},"x-codeSamples":[{"lang":"javascript","label":"Node","source":"import { createHmac, timingSafeEqual } from \"node:crypto\";\n\n// rawBody: the request body exactly as received, before JSON parsing.\nexport function verify(secret, headers, rawBody, toleranceSeconds = 300) {\n  const timestamp = headers[\"x-listonce-timestamp\"];\n  const signature = headers[\"x-listonce-signature\"] ?? \"\";\n  if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false;\n  const expected = \"sha256=\" + createHmac(\"sha256\", secret).update(`${timestamp}.${rawBody}`).digest(\"hex\");\n  return signature.length === expected.length && timingSafeEqual(Buffer.from(signature), Buffer.from(expected));\n}\n"},{"lang":"python","label":"Python","source":"import hashlib\nimport hmac\nimport time\n\n# raw_body: the request body bytes exactly as received, before JSON parsing.\ndef verify(secret: str, headers, raw_body: bytes, tolerance_seconds: int = 300) -> bool:\n    timestamp = headers.get(\"X-ListOnce-Timestamp\", \"\")\n    signature = headers.get(\"X-ListOnce-Signature\", \"\")\n    if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > tolerance_seconds:\n        return False\n    signed = timestamp.encode() + b\".\" + raw_body\n    expected = \"sha256=\" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, signature)\n"}]}},"listing.conflict":{"post":{"operationId":"listing_conflict","summary":"Same address as another brokerage","description":"Sent to the owners of both listings when a listing is entered at, or moved to, the address of another brokerage's active listing, and again when the platform operator decides it. Read /api/v1/conflicts?listing={listingKey} for the details. Never sent to licensees.","tags":["Webhooks"],"security":[],"parameters":[{"name":"X-ListOnce-Signature","in":"header","required":true,"description":"`sha256=` then the hex HMAC SHA-256 of `timestamp.body` under the webhook's secret.","schema":{"type":"string","pattern":"^sha256=[0-9a-f]{64}$"}},{"name":"X-ListOnce-Timestamp","in":"header","required":true,"description":"Unix seconds when this attempt was signed. Refuse old ones to stop replays.","schema":{"type":"string","pattern":"^\\d{10}$"}},{"name":"X-ListOnce-Delivery","in":"header","required":true,"description":"Stable across retries; equals the payload id. Dedupe on it.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"},"example":{"id":"OL-4K7Q2M:5:a7a332fd-bef7-4c6a-a362-9e9a3467e2d8","event":"listing.conflict","listingKey":"OL-4K7Q2M","status":"Pending","updatedAt":"2026-10-26T16:40:05.902+00:00"}}}},"responses":{"200":{"description":"Any 2xx within 8 seconds counts as received. Anything else, a redirect or a timeout is retried."}},"x-codeSamples":[{"lang":"javascript","label":"Node","source":"import { createHmac, timingSafeEqual } from \"node:crypto\";\n\n// rawBody: the request body exactly as received, before JSON parsing.\nexport function verify(secret, headers, rawBody, toleranceSeconds = 300) {\n  const timestamp = headers[\"x-listonce-timestamp\"];\n  const signature = headers[\"x-listonce-signature\"] ?? \"\";\n  if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false;\n  const expected = \"sha256=\" + createHmac(\"sha256\", secret).update(`${timestamp}.${rawBody}`).digest(\"hex\");\n  return signature.length === expected.length && timingSafeEqual(Buffer.from(signature), Buffer.from(expected));\n}\n"},{"lang":"python","label":"Python","source":"import hashlib\nimport hmac\nimport time\n\n# raw_body: the request body bytes exactly as received, before JSON parsing.\ndef verify(secret: str, headers, raw_body: bytes, tolerance_seconds: int = 300) -> bool:\n    timestamp = headers.get(\"X-ListOnce-Timestamp\", \"\")\n    signature = headers.get(\"X-ListOnce-Signature\", \"\")\n    if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > tolerance_seconds:\n        return False\n    signed = timestamp.encode() + b\".\" + raw_body\n    expected = \"sha256=\" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, signature)\n"}]}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key as a Bearer token. Scopes: listings:write, listings:read, feed:read, webhooks:manage. The read only sandbox key is ol_demo_7f3a9c2e5b1d4086."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"The HTTP status as text.","pattern":"^\\d{3}$"},"message":{"type":"string","description":"What to fix."},"existingKey":{"type":"string","description":"On a 409 for a duplicate address: the brokerage's active listing there.","pattern":"^OL-[A-Z0-9]{6}$"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"ODataError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"The HTTP status as text.","pattern":"^\\d{3}$"},"message":{"type":"string","description":"What to fix."},"target":{"type":"string","description":"The operation.","enum":["Create","Update"]},"existingKey":{"type":"string","description":"On a 409 for a duplicate address: the brokerage's active listing there.","pattern":"^OL-[A-Z0-9]{6}$"},"details":{"type":"array","description":"One entry per field at fault.","items":{"type":"object","properties":{"code":{"type":"string","description":"The HTTP status as text.","pattern":"^\\d{3}$"},"target":{"type":"string","description":"The RESO field."},"message":{"type":"string","description":"What to fix."}},"required":["code","target","message"],"additionalProperties":false}}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"PropertyCreate":{"type":"object","properties":{"UnparsedAddress":{"type":"string","minLength":1,"description":"Street, city, state ZIP. The text before the first comma is stored as the street (1 to 120 characters, no < or >); city, state and ZIP come from their own fields."},"City":{"type":"string","enum":["Austin","Charlotte","Phoenix","Tampa"],"description":"Pilot market."},"StateOrProvince":{"type":"string","enum":["TX","NC","AZ","FL"],"description":"Two letter state; must match the city."},"PostalCode":{"type":"string","pattern":"^\\d{5}$","description":"5 digit ZIP."},"ListPrice":{"type":"integer","minimum":1,"maximum":1000000000,"description":"List price in whole dollars."},"BedroomsTotal":{"type":"integer","minimum":0,"maximum":50,"description":"Bedrooms."},"BathroomsFull":{"type":"integer","minimum":0,"maximum":50,"description":"Full bathrooms. Send with BathroomsHalf."},"BathroomsHalf":{"type":"integer","minimum":0,"maximum":50,"description":"Half bathrooms, each counted as 0.5. Send with BathroomsFull (0 when there is none)."},"BathroomsTotalInteger":{"type":"integer","minimum":0,"maximum":50,"description":"Used only when BathroomsFull and BathroomsHalf are absent."},"LivingArea":{"type":"integer","minimum":0,"maximum":100000,"description":"Living area in square feet."},"LivingAreaUnits":{"type":"string","description":"Only Square Feet.","enum":["Square Feet"]},"LotSizeAcres":{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01,"description":"Lot size in acres."},"YearBuilt":{"type":"integer","minimum":1700,"maximum":2030,"description":"Year built."},"PropertyType":{"type":"string","description":"Only Residential.","enum":["Residential"]},"PropertySubType":{"type":"string","description":"RESO PropertySubType.","enum":["Single Family Residence","Townhouse","Condominium","Multi Family"]},"PublicRemarks":{"type":"string","minLength":1,"maxLength":2000,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Public remarks. Not blank, no < or >."},"ListAgentFullName":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Listing agent's name. Cannot change after entry. Not blank, no < or >."},"ListingContractDate":{"type":"string","format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The day the listing agreement was signed. Within the last year, not after tomorrow (UTC). Cannot change after entry."},"StandardStatus":{"type":"string","description":"Optional on create; must match the seller's choice.","enum":["Active","Coming Soon"]},"OnMarketDate":{"type":"string","format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Go live date, required for coming_soon. Not in the past. Ignored for other choices."},"LO_SellerVisibilityChoice":{"type":"string","enum":["public","coming_soon","members_only"],"description":"Extension: the seller's choice: public, coming_soon or members_only."},"LO_SellerName":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Extension: the seller's name. Write only: seen by the owner, never in the feed. Cannot change after entry. Not blank, no < or >."},"ListingKey":{"type":["string","null"],"description":"We assign the key; on a PATCH, any other key than the record's own is refused. Read only: ignored."},"OriginatingSystemName":{"type":["string","null"],"description":"Always this platform. Read only: ignored."},"ListOfficeName":{"type":["string","null"],"description":"The caller's brokerage. Read only: ignored."},"ModificationTimestamp":{"type":["string","null"],"description":"Set on every change. Read only: ignored."},"LO_SellerChoiceRecordedAt":{"type":["string","null"],"description":"Set when the choice changes. Read only: ignored."}},"required":["UnparsedAddress","City","StateOrProvince","PostalCode","ListPrice","BedroomsTotal","LivingArea","PropertySubType","PublicRemarks","ListAgentFullName","ListingContractDate","LO_SellerVisibilityChoice","LO_SellerName"],"additionalProperties":false},"PropertyPatch":{"type":"object","properties":{"UnparsedAddress":{"type":"string","minLength":1,"description":"Street, city, state ZIP. The text before the first comma is stored as the street (1 to 120 characters, no < or >); city, state and ZIP come from their own fields."},"City":{"type":"string","enum":["Austin","Charlotte","Phoenix","Tampa"],"description":"Pilot market."},"StateOrProvince":{"type":"string","enum":["TX","NC","AZ","FL"],"description":"Two letter state; must match the city."},"PostalCode":{"type":"string","pattern":"^\\d{5}$","description":"5 digit ZIP."},"ListPrice":{"type":"integer","minimum":1,"maximum":1000000000,"description":"List price in whole dollars."},"BedroomsTotal":{"type":"integer","minimum":0,"maximum":50,"description":"Bedrooms."},"BathroomsFull":{"type":"integer","minimum":0,"maximum":50,"description":"Full bathrooms. Send with BathroomsHalf."},"BathroomsHalf":{"type":"integer","minimum":0,"maximum":50,"description":"Half bathrooms, each counted as 0.5. Send with BathroomsFull (0 when there is none)."},"BathroomsTotalInteger":{"type":"integer","minimum":0,"maximum":50,"description":"Used only when BathroomsFull and BathroomsHalf are absent."},"LivingArea":{"type":"integer","minimum":0,"maximum":100000,"description":"Living area in square feet."},"LivingAreaUnits":{"type":"string","description":"Only Square Feet.","enum":["Square Feet"]},"LotSizeAcres":{"type":["number","null"],"minimum":0,"maximum":100000,"multipleOf":0.01,"description":"Lot size in acres. null clears it."},"YearBuilt":{"type":["integer","null"],"minimum":1700,"maximum":2030,"description":"Year built. null clears it."},"PropertyType":{"type":"string","description":"Only Residential.","enum":["Residential"]},"PropertySubType":{"type":"string","description":"RESO PropertySubType.","enum":["Single Family Residence","Townhouse","Condominium","Multi Family"]},"PublicRemarks":{"type":"string","minLength":1,"maxLength":2000,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Public remarks. Not blank, no < or >."},"ListAgentFullName":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Listing agent's name. Cannot change after entry. Not blank, no < or >."},"ListingContractDate":{"type":"string","format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The day the listing agreement was signed. Within the last year, not after tomorrow (UTC). Cannot change after entry."},"StandardStatus":{"type":"string","enum":["Coming Soon","Active","Pending","Closed","Withdrawn"],"description":"New status."},"OnMarketDate":{"type":["string","null"],"format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Go live date while Coming Soon; ignored otherwise."},"LO_SellerVisibilityChoice":{"type":"string","enum":["public","coming_soon","members_only"],"description":"Extension: the seller's choice: public, coming_soon or members_only."},"LO_SellerName":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Extension: the seller's name. Write only: seen by the owner, never in the feed. Cannot change after entry. Not blank, no < or >."},"ListingKey":{"type":["string","null"],"description":"We assign the key; on a PATCH, any other key than the record's own is refused. Read only: ignored."},"OriginatingSystemName":{"type":["string","null"],"description":"Always this platform. Read only: ignored."},"ListOfficeName":{"type":["string","null"],"description":"The caller's brokerage. Read only: ignored."},"ModificationTimestamp":{"type":["string","null"],"description":"Set on every change. Read only: ignored."},"LO_SellerChoiceRecordedAt":{"type":["string","null"],"description":"Set when the choice changes. Read only: ignored."},"ClosePrice":{"type":["integer","null"],"minimum":1,"maximum":1000000000,"description":"Sold price; only when the status is Closed. null is ignored."}},"required":[],"additionalProperties":false,"minProperties":1},"PropertyWritten":{"type":"object","properties":{"@odata.context":{"type":"string","description":"OData context: the $metadata document and the entity.","format":"uri"},"ListingKey":{"type":"string","description":"Listing key."},"OriginatingSystemName":{"type":"string","description":"Always this platform."},"StandardStatus":{"type":"string","description":"RESO StandardStatus.","enum":["Coming Soon","Active","Pending","Closed","Withdrawn"]},"ListPrice":{"type":"integer","description":"List price."},"ClosePrice":{"type":["integer","null"],"description":"Sold price, when Closed."},"UnparsedAddress":{"type":"string","description":"Street, city, state ZIP."},"City":{"type":"string","description":"City."},"StateOrProvince":{"type":"string","description":"State."},"PostalCode":{"type":"string","description":"ZIP."},"PropertyType":{"type":"string","description":"Always Residential.","enum":["Residential"]},"PropertySubType":{"type":"string","description":"RESO PropertySubType.","enum":["Single Family Residence","Townhouse","Condominium","Multi Family"]},"BedroomsTotal":{"type":"integer","description":"Bedrooms."},"BathroomsTotalInteger":{"type":"integer","description":"Bathrooms counted whole: 2 full and 1 half is 3."},"BathroomsFull":{"type":"integer","description":"Full bathrooms."},"BathroomsHalf":{"type":"integer","description":"Half bathrooms."},"LivingArea":{"type":"integer","description":"Living area."},"LivingAreaUnits":{"type":"string","description":"Always Square Feet.","enum":["Square Feet"]},"LotSizeAcres":{"type":["number","null"],"description":"Lot size in acres."},"YearBuilt":{"type":["integer","null"],"description":"Year built."},"PublicRemarks":{"type":"string","description":"Public remarks."},"ListAgentFullName":{"type":"string","description":"Listing agent."},"ListOfficeName":{"type":"string","description":"Listing brokerage."},"ListingContractDate":{"type":"string","description":"Agreement date.","format":"date"},"OnMarketDate":{"type":"string","description":"Go live date while Coming Soon, else the day it went on the market.","format":"date"},"ModificationTimestamp":{"type":"string","description":"Last change.","format":"date-time"},"LO_SellerVisibilityChoice":{"type":"string","description":"Extension: the seller's choice.","enum":["public","coming_soon","members_only"]},"LO_SellerChoiceRecordedAt":{"type":"string","description":"Extension: when the seller's choice was recorded.","format":"date-time"}},"required":["@odata.context","ListingKey","OriginatingSystemName","StandardStatus","ListPrice","ClosePrice","UnparsedAddress","City","StateOrProvince","PostalCode","PropertyType","PropertySubType","BedroomsTotal","BathroomsTotalInteger","BathroomsFull","BathroomsHalf","LivingArea","LivingAreaUnits","LotSizeAcres","YearBuilt","PublicRemarks","ListAgentFullName","ListOfficeName","ListingContractDate","OnMarketDate","ModificationTimestamp","LO_SellerVisibilityChoice","LO_SellerChoiceRecordedAt"],"additionalProperties":false},"ListingCreate":{"type":"object","properties":{"street":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Street address. Not blank, no < or >."},"city":{"type":"string","enum":["Austin","Charlotte","Phoenix","Tampa"],"description":"Pilot market."},"state":{"type":"string","enum":["TX","NC","AZ","FL"],"description":"Two letter state; must match the city."},"zip":{"type":"string","pattern":"^\\d{5}$","description":"5 digit ZIP."},"price":{"type":"integer","minimum":1,"maximum":1000000000,"description":"List price in whole dollars."},"beds":{"type":"integer","minimum":0,"maximum":50,"description":"Bedrooms."},"baths":{"type":"number","minimum":0,"maximum":50,"multipleOf":0.5,"description":"Bathrooms, in halves."},"sqft":{"type":"integer","minimum":0,"maximum":100000,"description":"Living area in square feet."},"lotAcres":{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01,"description":"Lot size in acres."},"yearBuilt":{"type":"integer","minimum":1700,"maximum":2030,"description":"Year built."},"propertyType":{"type":"string","enum":["Single Family","Townhouse","Condominium","Multi Family"],"description":"Property sub type."},"remarks":{"type":"string","minLength":1,"maxLength":2000,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Public remarks. Not blank, no < or >."},"agent":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Listing agent's name. Not blank, no < or >."},"seller":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Seller's name. Seen only by the owner. Not blank, no < or >."},"visibility":{"type":"string","enum":["public","coming_soon","members_only"],"description":"The seller's choice: public (the usual one), coming_soon or members_only."},"goLiveDate":{"type":"string","format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Required for coming_soon. Not in the past."},"listingAgreementAt":{"type":"string","format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The day the listing agreement was signed. Within the last year, not after tomorrow (UTC)."}},"required":["street","city","state","zip","price","beds","baths","sqft","propertyType","remarks","agent","seller","visibility","listingAgreementAt"],"additionalProperties":false},"ListingPatch":{"type":"object","properties":{"street":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Street address. Not blank, no < or >."},"city":{"type":"string","enum":["Austin","Charlotte","Phoenix","Tampa"],"description":"Pilot market."},"state":{"type":"string","enum":["TX","NC","AZ","FL"],"description":"Two letter state; must match the city."},"zip":{"type":"string","pattern":"^\\d{5}$","description":"5 digit ZIP."},"price":{"type":"integer","minimum":1,"maximum":1000000000,"description":"List price in whole dollars."},"beds":{"type":"integer","minimum":0,"maximum":50,"description":"Bedrooms."},"baths":{"type":"number","minimum":0,"maximum":50,"multipleOf":0.5,"description":"Bathrooms, in halves."},"sqft":{"type":"integer","minimum":0,"maximum":100000,"description":"Living area in square feet."},"lotAcres":{"type":["number","null"],"minimum":0,"maximum":100000,"multipleOf":0.01,"description":"Lot size in acres. null clears it."},"yearBuilt":{"type":["integer","null"],"minimum":1700,"maximum":2030,"description":"Year built. null clears it."},"propertyType":{"type":"string","enum":["Single Family","Townhouse","Condominium","Multi Family"],"description":"Property sub type."},"remarks":{"type":"string","minLength":1,"maxLength":2000,"pattern":"^[^<>\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]*$","description":"Public remarks. Not blank, no < or >."},"status":{"type":"string","enum":["Coming Soon","Active","Pending","Closed","Withdrawn"],"description":"New status."},"visibility":{"type":"string","enum":["public","coming_soon","members_only"],"description":"A new seller choice."},"goLiveDate":{"type":"string","format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Go live date for coming soon. Not in the past."},"soldPrice":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Sold price; only when the status is Closed."},"resend":{"type":"boolean","description":"Clear send backs and resend everywhere."}},"required":[],"additionalProperties":false,"minProperties":1},"Delivery":{"type":"object","properties":{"destId":{"type":"string","description":"Destination id."},"state":{"type":"string","description":"Outcome.","enum":["queued","validating","delivered","held","waiting","removed"]},"at":{"type":"string","description":"When this outcome was set.","format":"date-time"},"note":{"type":"string","description":"Why it is held, waiting or shown differently."}},"required":["destId","state","at"],"additionalProperties":false},"HistoryLine":{"type":"object","properties":{"at":{"type":"string","description":"When.","format":"date-time"},"who":{"type":"string","description":"Agent, brokerage or the platform."},"what":{"type":"string","description":"What happened."},"hash":{"type":"string","description":"Fingerprint over this line and the one before.","pattern":"^[0-9a-f]{14}$"}},"required":["at","who","what","hash"],"additionalProperties":false},"Listing":{"type":"object","properties":{"id":{"type":"string","description":"Listing key.","pattern":"^OL-[A-Z0-9]{6}$"},"addressKey":{"type":"string","description":"The canonical address: number|street|unit|city|state|zip, upper case, with St, Ave, Apt, # and the like spelled one way. Two active listings with one key are the same home."},"street":{"type":"string","description":"Street address."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State."},"zip":{"type":"string","description":"ZIP."},"price":{"type":"integer","description":"List price."},"beds":{"type":"integer","description":"Bedrooms."},"baths":{"type":"number","description":"Bathrooms."},"sqft":{"type":"integer","description":"Living area."},"lotAcres":{"type":"number","description":"Lot size in acres."},"yearBuilt":{"type":"integer","description":"Year built."},"propertyType":{"type":"string","description":"Property sub type."},"remarks":{"type":"string","description":"Public remarks."},"agent":{"type":"string","description":"Listing agent."},"brokerage":{"type":"string","description":"Listing brokerage: the owner."},"seller":{"type":"string","description":"Seller."},"source":{"type":"string","description":"Where it was entered.","enum":["form","rezen","api","mls"]},"visibility":{"type":"string","description":"The seller's choice.","enum":["public","coming_soon","members_only"]},"status":{"type":"string","description":"Status.","enum":["Coming Soon","Active","Pending","Closed","Withdrawn"]},"goLiveDate":{"type":"string","description":"Go live date for coming soon.","format":"date"},"soldPrice":{"type":"integer","description":"Sold price, when Closed."},"photos":{"type":"array","items":{"type":"string","format":"uri"},"description":"Signed links to the photos, first (preferred) first, lasting about 12 hours. Empty when the listing is created; photos are added under /media."},"listingAgreementAt":{"type":"string","description":"Agreement date.","format":"date"},"sellerConsentAt":{"type":"string","description":"When the seller's current choice was recorded.","format":"date-time"},"sellerApprovedAt":{"type":"string","description":"When the seller approved it on their page.","format":"date-time"},"returns":{"type":"object","additionalProperties":{"type":"string"},"description":"Open MLS send backs: destination id to reason."},"createdAt":{"type":"string","description":"Entered.","format":"date-time"},"updatedAt":{"type":"string","description":"Last change.","format":"date-time"},"tint":{"type":"integer","description":"Cover art color for the demo pages."},"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"},"description":"Outcome per destination."},"history":{"type":"array","items":{"$ref":"#/components/schemas/HistoryLine"},"description":"Append only, oldest first."},"historyIntact":{"type":"boolean","description":"Every fingerprint verifies."},"lateDays":{"type":"integer","description":"Days past the one business day entry deadline; 0 when on time."},"origin":{"type":"object","properties":{"mls":{"type":"string","description":"The MLS it was entered at."},"key":{"type":"string","description":"That MLS's key for it."}},"required":["mls","key"],"additionalProperties":false},"mlsNumbers":{"type":"object","additionalProperties":{"type":"string"},"description":"MLS numbers the agent recorded after entering the listing in an MLS from its pre-filled draft in the console: destination id to MLS number."},"remarkFlags":{"type":"array","items":{"type":"object","properties":{"phrase":{"type":"string","description":"The phrase found."},"why":{"type":"string","description":"The fair housing concern."}},"required":["phrase","why"],"additionalProperties":false},"description":"Phrases to review. A prompt, not a block."}},"required":["id","street","city","state","zip","price","beds","baths","sqft","propertyType","remarks","agent","brokerage","seller","source","visibility","status","photos","listingAgreementAt","sellerConsentAt","returns","createdAt","updatedAt","tint","deliveries","history","historyIntact","lateDays","remarkFlags"],"additionalProperties":false},"DeliveryList":{"type":"object","properties":{"listingKey":{"type":"string","description":"Listing key."},"value":{"type":"array","items":{"type":"object","properties":{"destId":{"type":"string","description":"Destination id."},"state":{"type":"string","description":"Outcome.","enum":["queued","validating","delivered","held","waiting","removed"]},"at":{"type":"string","description":"When this outcome was set.","format":"date-time"},"note":{"type":"string","description":"Why it is held, waiting or shown differently."},"destination":{"type":"string","description":"Destination name."},"kind":{"type":"string","description":"Destination kind.","enum":["mls","portal","network","data"]}},"required":["destId","state","at","destination","kind"],"additionalProperties":false}}},"required":["listingKey","value"],"additionalProperties":false},"ExportPage":{"type":"object","properties":{"organization":{"type":"string","description":"The caller's brokerage."},"exportedAt":{"type":"string","description":"When this page was read.","format":"date-time"},"value":{"type":"array","items":{"$ref":"#/components/schemas/Listing"},"description":"This page, by listing key."},"nextLink":{"type":"string","description":"The next page, while there is one.","format":"uri"}},"required":["organization","exportedAt","value"],"additionalProperties":false},"Property":{"type":"object","properties":{"@odata.context":{"type":"string","description":"OData context: the $metadata document and the entity.","format":"uri"},"ListingKey":{"type":"string","description":"Listing key."},"OriginatingSystemName":{"type":"string","description":"Always this platform."},"StandardStatus":{"type":"string","description":"RESO StandardStatus.","enum":["Active","Pending","Closed","Withdrawn"]},"ListPrice":{"type":"integer","description":"List price."},"ClosePrice":{"type":["integer","null"],"description":"Sold price, when Closed."},"UnparsedAddress":{"type":"string","description":"Street, city, state ZIP."},"City":{"type":"string","description":"City."},"StateOrProvince":{"type":"string","description":"State."},"PostalCode":{"type":"string","description":"ZIP."},"PropertyType":{"type":"string","description":"Always Residential.","enum":["Residential"]},"PropertySubType":{"type":"string","description":"RESO PropertySubType.","enum":["Single Family Residence","Townhouse","Condominium","Multi Family"]},"BedroomsTotal":{"type":"integer","description":"Bedrooms."},"BathroomsTotalInteger":{"type":"integer","description":"Bathrooms counted whole: 2 full and 1 half is 3."},"BathroomsFull":{"type":"integer","description":"Full bathrooms."},"BathroomsHalf":{"type":"integer","description":"Half bathrooms."},"LivingArea":{"type":"integer","description":"Living area."},"LivingAreaUnits":{"type":"string","description":"Always Square Feet.","enum":["Square Feet"]},"LotSizeAcres":{"type":["number","null"],"description":"Lot size in acres."},"YearBuilt":{"type":["integer","null"],"description":"Year built."},"PublicRemarks":{"type":"string","description":"Public remarks."},"ListAgentFullName":{"type":"string","description":"Listing agent."},"ListOfficeName":{"type":"string","description":"Listing brokerage."},"ListingContractDate":{"type":"string","description":"Agreement date.","format":"date"},"OnMarketDate":{"type":"string","description":"Day it went on the market.","format":"date"},"ModificationTimestamp":{"type":"string","description":"Last change.","format":"date-time"},"LO_SellerVisibilityChoice":{"type":"string","description":"Extension: the seller's choice. Members only never appears here.","enum":["public","coming_soon"]},"LO_SellerChoiceRecordedAt":{"type":"string","description":"Extension: when the seller's choice was recorded.","format":"date-time"},"Media":{"type":"array","items":{"$ref":"#/components/schemas/Media"},"description":"With $expand=Media: the photos, in order."}},"required":["ListingKey","OriginatingSystemName","StandardStatus","ListPrice","ClosePrice","UnparsedAddress","City","StateOrProvince","PostalCode","PropertyType","PropertySubType","BedroomsTotal","BathroomsTotalInteger","BathroomsFull","BathroomsHalf","LivingArea","LivingAreaUnits","LotSizeAcres","YearBuilt","PublicRemarks","ListAgentFullName","ListOfficeName","ListingContractDate","OnMarketDate","ModificationTimestamp","LO_SellerVisibilityChoice","LO_SellerChoiceRecordedAt"],"additionalProperties":false},"MemberCopy":{"type":"object","properties":{"ListingKey":{"type":"string","description":"This recipient's alias for the listing, not its key.","pattern":"^OLM-[A-HJ-NP-Z2-9]{10}$"},"OriginatingSystemName":{"type":"string","description":"Always this platform."},"StandardStatus":{"type":"string","description":"RESO StandardStatus.","enum":["Active","Pending","Closed","Withdrawn"]},"ListPrice":{"type":"integer","description":"List price."},"ClosePrice":{"type":["integer","null"],"description":"Sold price, when Closed."},"UnparsedAddress":{"type":"string","description":"Street, city, state ZIP."},"City":{"type":"string","description":"City."},"StateOrProvince":{"type":"string","description":"State."},"PostalCode":{"type":"string","description":"ZIP."},"PropertyType":{"type":"string","description":"Always Residential.","enum":["Residential"]},"PropertySubType":{"type":"string","description":"RESO PropertySubType.","enum":["Single Family Residence","Townhouse","Condominium","Multi Family"]},"BedroomsTotal":{"type":"integer","description":"Bedrooms."},"BathroomsTotalInteger":{"type":"integer","description":"Bathrooms counted whole: 2 full and 1 half is 3."},"BathroomsFull":{"type":"integer","description":"Full bathrooms."},"BathroomsHalf":{"type":"integer","description":"Half bathrooms."},"LivingArea":{"type":"integer","description":"Living area."},"LivingAreaUnits":{"type":"string","description":"Always Square Feet.","enum":["Square Feet"]},"LotSizeAcres":{"type":["number","null"],"description":"Lot size in acres."},"YearBuilt":{"type":["integer","null"],"description":"Year built."},"PublicRemarks":{"type":"string","description":"Public remarks."},"ListAgentFullName":{"type":"string","description":"Listing agent."},"ListOfficeName":{"type":"string","description":"Listing brokerage."},"ListingContractDate":{"type":"string","description":"Agreement date.","format":"date"},"OnMarketDate":{"type":"string","description":"Day it went on the market.","format":"date"},"ModificationTimestamp":{"type":"string","description":"Last change.","format":"date-time"},"LO_SellerVisibilityChoice":{"type":"string","description":"Always members_only here.","enum":["members_only"]},"LO_SellerChoiceRecordedAt":{"type":"string","description":"Extension: when the seller's choice was recorded.","format":"date-time"},"Media":{"type":"array","items":{"$ref":"#/components/schemas/Media"},"description":"Photos at /p/{token}/{n} URLs issued to this recipient only, each fetch logged; MediaKey and ResourceRecordKey are made from the alias. A listing with no photos gets one drawn stand in at /p/{token}."},"LO_MembersOnly":{"type":"boolean","description":"Always true."},"LO_Notice":{"type":"string","description":"Members only: never publicly marketed."}},"required":["ListingKey","OriginatingSystemName","StandardStatus","ListPrice","ClosePrice","UnparsedAddress","City","StateOrProvince","PostalCode","PropertyType","PropertySubType","BedroomsTotal","BathroomsTotalInteger","BathroomsFull","BathroomsHalf","LivingArea","LivingAreaUnits","LotSizeAcres","YearBuilt","PublicRemarks","ListAgentFullName","ListOfficeName","ListingContractDate","OnMarketDate","ModificationTimestamp","LO_SellerVisibilityChoice","LO_SellerChoiceRecordedAt","Media","LO_MembersOnly","LO_Notice"],"additionalProperties":false},"Media":{"type":"object","properties":{"MediaKey":{"type":"string","description":"Photo key."},"ResourceRecordKey":{"type":"string","description":"The listing's key (an alias in a members only copy)."},"ResourceName":{"type":"string","description":"Always Property.","enum":["Property"]},"MediaCategory":{"type":"string","description":"Always Photo.","enum":["Photo"]},"MediaURL":{"type":"string","description":"A signed link to the JPEG on this host.","format":"uri"},"Order":{"type":"integer","description":"Position from 0."},"ImageWidth":{"type":"integer","description":"Pixels; at most 2560 on the long side."},"ImageHeight":{"type":"integer","description":"Pixels."},"PreferredPhotoYN":{"type":"boolean","description":"True for the first photo."},"ModificationTimestamp":{"type":"string","description":"When it was added or last moved.","format":"date-time"}},"required":["MediaKey","ResourceRecordKey","ResourceName","MediaCategory","MediaURL","Order","ImageWidth","ImageHeight","PreferredPhotoYN","ModificationTimestamp"],"additionalProperties":false},"MediaList":{"type":"object","properties":{"listingKey":{"type":"string","description":"Listing key."},"value":{"type":"array","items":{"$ref":"#/components/schemas/Media"},"description":"Photos, in order."}},"required":["listingKey","value"],"additionalProperties":false},"MediaUpload":{"type":"object","properties":{"uploadId":{"type":"string","description":"Send it to POST /media once the file is PUT.","format":"uuid"},"uploadUrl":{"type":"string","description":"One time URL: PUT the file here as the raw body with its Content-Type.","format":"uri"},"method":{"type":"string","description":"Always PUT.","enum":["PUT"]},"expiresAt":{"type":"string","description":"The URL stops working.","format":"date-time"},"maxBytes":{"type":"integer","description":"Largest file accepted."},"contentTypes":{"type":"array","items":{"type":"string"},"description":"Accepted Content-Types."}},"required":["uploadId","uploadUrl","method","expiresAt","maxBytes","contentTypes"],"additionalProperties":false},"MediaAdd":{"type":"object","properties":{"uploadId":{"type":"string","description":"From the upload step.","format":"uuid"}},"required":["uploadId"],"additionalProperties":false},"MediaOrder":{"type":"object","properties":{"order":{"type":"array","items":{"type":"string","pattern":"^OLP-[A-HJ-NP-Z2-9]{10}$"},"description":"Every MediaKey of the listing once, first is preferred. 1 to 25."}},"required":["order"],"additionalProperties":false},"MediaPage":{"type":"object","properties":{"@odata.context":{"type":"string","description":"OData context: the $metadata document and the entity set.","format":"uri"},"@odata.count":{"type":"integer","description":"Records matching the filter, with $count=true."},"value":{"type":"array","items":{"$ref":"#/components/schemas/Media"},"description":"This page. With $select, each record holds only the fields named."},"@odata.nextLink":{"type":"string","description":"The next page, when the server cut this one short.","format":"uri"}},"required":["@odata.context","value"],"additionalProperties":false},"PropertyPage":{"type":"object","properties":{"@odata.context":{"type":"string","description":"OData context: the $metadata document and the entity set.","format":"uri"},"@odata.count":{"type":"integer","description":"Records matching the filter, with $count=true."},"value":{"type":"array","items":{"$ref":"#/components/schemas/Property"},"description":"This page. With $select, each record holds only the fields named."},"@odata.nextLink":{"type":"string","description":"The next page, when the server cut this one short.","format":"uri"}},"required":["@odata.context","value"],"additionalProperties":false},"WebhookCreate":{"type":"object","properties":{"url":{"type":"string","description":"https URL on the standard port.","maxLength":500,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["listing.created","listing.updated","listing.conflict"]},"description":"Defaults to listing.created and listing.updated. listing.conflict is sent only when asked for, and only member brokerages may ask (400 otherwise). Duplicates are dropped."}},"required":["url"],"additionalProperties":false},"WebhookCreated":{"type":"object","properties":{"id":{"type":"string","description":"Webhook id.","format":"uuid"},"url":{"type":"string","description":"Where events go."},"events":{"type":"array","items":{"type":"string","enum":["listing.created","listing.updated","listing.conflict"]},"description":"Subscribed events."},"active":{"type":"boolean","description":"Receiving events."},"createdAt":{"type":"string","description":"Created.","format":"date-time"},"secret":{"type":"string","description":"Signing secret. Shown once.","pattern":"^whsec_[0-9a-f]{48}$"}},"required":["id","url","events","active","createdAt","secret"],"additionalProperties":false},"WebhookList":{"type":"object","properties":{"value":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Webhook id.","format":"uuid"},"url":{"type":"string","description":"Where events go."},"events":{"type":"array","items":{"type":"string","enum":["listing.created","listing.updated","listing.conflict"]},"description":"Subscribed events."},"active":{"type":"boolean","description":"Receiving events."},"createdAt":{"type":"string","description":"Created.","format":"date-time"},"lastDelivery":{"oneOf":[{"type":"object","properties":{"status":{"type":"string","description":"Delivery state.","enum":["pending","sent","failed"]},"code":{"type":["integer","null"],"description":"Last HTTP status; 0 for no response."},"attempts":{"type":"integer","description":"Attempts so far."},"at":{"type":"string","description":"When the event was queued.","format":"date-time"}},"required":["status","code","attempts","at"],"additionalProperties":false},{"type":"null"}],"description":"The most recent delivery, or null."}},"required":["id","url","events","active","createdAt","lastDelivery"],"additionalProperties":false}}},"required":["value"],"additionalProperties":false},"ConflictList":{"type":"object","properties":{"value":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Conflict id.","format":"uuid"},"status":{"type":"string","description":"open until the platform operator decides it.","enum":["open","co_listing","wrong_address","resolved"]},"listingKey":{"type":"string","description":"Your listing."},"other":{"type":"object","properties":{"listingKey":{"type":"string","description":"The other brokerage's listing."},"brokerage":{"type":"string","description":"The other brokerage."},"status":{"type":"string","description":"Its status.","enum":["Coming Soon","Active","Pending","Closed","Withdrawn"]}},"required":["listingKey","brokerage","status"],"additionalProperties":false},"wrongListing":{"type":["string","null"],"description":"With wrong_address: the listing whose address is wrong."},"createdAt":{"type":"string","description":"When it was flagged.","format":"date-time"},"decidedAt":{"type":["string","null"],"format":"date-time","description":"When it was decided."}},"required":["id","status","listingKey","other","wrongListing","createdAt","decidedAt"],"additionalProperties":false}}},"required":["value"],"additionalProperties":false},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id: listing key, history line, webhook id. Equals the delivery header."},"event":{"type":"string","description":"Event name.","enum":["listing.created","listing.updated","listing.conflict"]},"listingKey":{"type":"string","description":"The listing. Read it for the details."},"status":{"type":"string","description":"Status after the change.","enum":["Coming Soon","Active","Pending","Closed","Withdrawn"]},"updatedAt":{"type":"string","description":"When the listing changed.","format":"date-time"}},"required":["id","event","listingKey","status","updatedAt"],"additionalProperties":false}}}}