Overview
What the Novi Kvadrat partner API does, where it lives, how one request travels, and what it deliberately leaves out.
The Novi Kvadrat partner API lets real-estate software (a CRM, an export tool) publish its agencies' sale and rental listings on Novi Kvadrat — with each agency's consent. You push signed JSON; we validate it, stage it, and a worker turns it into listings exactly as the agency's own editor would.
Base URL#
https://novikvadrat.rs/api/partners/v1Sandbox and live use the same base URL. The key you sign with decides the environment: a sandbox key works only with your sandbox apps and their test connections, a live key only with your live app.
Who does what#
- You (the partner) sign up in the Partner Portal, register an Ed25519 public key, and call the API from your servers.
- An agency connects your software by generating a connect code in its own Novi Kvadrat portal and handing it to you. Nothing in a payload names an agency: the connection does.
- Novi Kvadrat staff approve your company, check the first listings of every new connection (certification), and create your live app.
The life of one request#
- You build the body bytes, compute
Content-Digest, pick a timestamp and a fresh nonce, build the NK-SIG-1 base (method, host, path with query, timestamp, nonce, digest) and sign it with your private key. See NK-SIG-1 signing. - You send the request to
https://novikvadrat.rs/api/partners/v1/…with the five signing headers andContent-Type: application/json. No request carries a body onDELETE; data for a delete travels in the signed query (?reason=), and removing a listing is aPOST …/removewith a body. - We check, in order: kill switch → body size (4 MiB) → headers → key → app and account → client IP → digest, time, signature → app rate → nonce. The first failure answers with its code; nothing is stored. See Errors.
- For a route that names a connection: the connection must belong to the signing app (else 404) and be
active(orcertifyingfor listing writes; else 409connection_not_activewithdetails.status). Listing writes then count against the connection's hourly item budget. - The body is validated against the v1 schema. A single
PUTthat fails answers 422; a batch answers 202 with per-itemrejectedresults (rejected items are not staged). - Valid items are staged and answered at once (
accepted,unchanged,needs_review). The worker importsaccepteditems of active connections within about a minute (photos can take longer and retry). Items of a paused connection wait and import after the agency resumes. - Final outcomes arrive as webhooks (
item.imported,item.failed, …), in the reconcile view and in the Partner Portal.GET /batches/{id}shows each item's push-time result (the answer from step 6) plus the link to its listing once one exists; it is not updated with the final outcome.
Every response carries NK-Request-Id (quote it to support) and Cache-Control: no-store.
What the API does not do#
- No search or browse of other agencies' listings.
- No lead or inquiry read (planned for a later version).
- No photo upload endpoint: photos are HTTPS URLs that our fetcher downloads.
- No admin or staff operations, no partner-side pause, no way to create an agency, and no way to name an agency except through a connect code.
Where to go next#
Questions? Write to partners@novikvadrat.rs.
Last updated