Skip to content
Sursa Developers

Move to the API address

Earlier integrations call the API on the main address of Sursa, the one people open in the browser, for example https://app.sursa.com/v1/…. The API now also has its own address, https://api.sursa.com in the cloud or https://api.<your domain> in your installation. It is built for integrations: it scales out behind a load balancer, and it serves nothing but the API.

You do not have to move. The main address keeps serving /v1 for existing integrations, with no end date and no redirect. Move when it suits you, to get the benefits of the API address, and use it for every new integration.

What stays the same

  • The paths, parameters, fields, error codes and events: GET /v1/cards is the same request on both addresses.
  • API keys. The same kb_ and kbsrc_ keys work on both addresses, with the same role, scopes and data profile.
  • Idempotency keys, rate limits and quotas. Requests on both addresses count toward the same quotas of the organization.
  • Webhooks. Deliveries, signatures and secrets do not depend on the address you call.
  • Links in responses. doc_url of an error points to this portal, and the Link header of a list page points to the API address, whichever address you call.

What is different on the API address

On the main addressOn the API address
Every endpoint of the web application, including internal onesOnly the endpoints of the public API reference. Any other path answers 404 with the code api.not_found.
A key in X-API-Key or Authorization, or a browser session cookieA key or an OAuth access token, preferably in Authorization: Bearer. Cookies are ignored.
GET /auth/meGET /v1/me. Paths under /auth/ are not served.
The "View as" mode by cookieThe X-View-As header, for keys with the admin role.
One server, or a fixed setSeveral servers behind a load balancer.

The last row matters for one case only: a streamed answer of POST /v1/chat. A dropped stream continues from Last-Event-ID only on the server that writes the answer. If your integration resumes streams, give every question a request_id, so that a retry on another server receives the saved answer instead of a second one. See Resume a dropped stream.

Before you move

Check that every call is public. List the paths your integration calls and look each one up in the API reference, or compare them with the specification of the new address:

curl -s https://api.example.com/openapi.json \
  | jq -r '.paths | to_entries[] | .key as $p | .value | keys[] | ascii_upcase + " " + $p' \
  | sort > public-operations.txt

A path that is missing from the public reference belongs to the web application. It still works on the main address, but it is not served on the API address, and its shape is not a public commitment. Replace it with a public endpoint, or keep that part of the integration on the main address and tell your Sursa contact what you need.

Check how you authenticate. If the integration signs in with a user's password and a session cookie, move it to an API key first. If it sends X-API-Key, switching to Authorization: Bearer is recommended but not required.

Check your network. Allow outgoing HTTPS to the new host name in your firewall and proxies.

Move step by step

  1. Make the base URL a setting of your integration, if it is not one already.

  2. Try the new address with a read request:

    curl https://api.example.com/v1/me -H "Authorization: Bearer $SURSA_API_KEY"
    
  3. Run the test suite of your integration against the new address, with a test key and a test collection.

  4. Switch a part of the traffic, for example one worker or one environment, and watch for 404 api.not_found, 401 and 5xx in your logs. Every response carries X-Request-Id; keep it with your logs.

  5. Switch the rest. Keep the old base URL in your configuration for a while so you can switch back in seconds.

Things to check after the move

  • GET /v1/health on the new address returns the same version as on the old one.
  • The RateLimit headers are present on responses. If your integration slows itself down by X-RateLimit-*, it can keep doing so: both sets are sent. See Rate limits and quotas.
  • If your integration runs in a browser, it no longer needs your own proxy for CORS: the API address allows requests from any origin, without cookies.