> ## Documentation Index
> Fetch the complete documentation index at: https://help.elationhealth.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Core Developer FAQ

> Answers to the questions Elation's Technical Solutions and Support teams field most often about Core Developer: pricing, credentials, the sandbox, the APIs, Webhooks, and the Hosted Database.

**CORE DEVELOPER · FAQ**

These are the questions we actually get asked, grouped by where they come up. Answers link out to the page that carries the full detail where there is one.

If your question isn't here, email [support@elationhealth.com](mailto:support@elationhealth.com).

***

**01 — PRICING AND CONTRACTS**

## What it costs and what's in the package

<AccordionGroup>
  <Accordion title="Do I need Core Developer, or can I just use the API?">
    It depends on who is building.

    If your practice or a consultant you hire is building a custom integration that your practice owns, you need Core Developer on your subscription before production credentials are issued. That covers REST API 2.0 read and write access, Webhooks, and the Hosted Database.

    If you are adopting an integration a vendor already built, you do not need Core Developer. That vendor's partner agreement with Elation governs access, and their credentials cannot be reused for a custom build of your own. Before you scope anything, check whether Elation already integrates with the partner you have in mind. See [Submitting an integration request](/articles/request-a-new-integration-to-elation).

    Not sure which side of the line you are on? See [Pricing and add-ons](/core-developer-pricing) to understand which path fits your situation.
  </Accordion>

  <Accordion title="Can I license Core Developer for only some of my providers?">
    No. Core Developer is an all-in add-on. The fee applies to every provider with an active EHR seat. Staff accounts are exempt.

    The reason is structural: clinical data from every provider in the practice flows into the Hosted Database and is reachable through the API. There is no way to carve one provider's data out, so there is no partial seat count to bill. See [how provider seats are counted](/core-developer-pricing).
  </Accordion>

  <Accordion title="Are part-time providers billed at the same rate?">
    Yes. Elation does not distinguish between part-time and full-time providers for Core Developer. Any provider account with an active EHR subscription counts as a seat.
  </Accordion>

  <Accordion title="Can I buy just the API, or just the Hosted Database?">
    No. Core Developer is sold as one package, with no API-only or Hosted-Database-only SKU.
  </Accordion>

  <Accordion title="Does Elation Analyst cost extra?">
    No. Elation Analyst *(Beta)* is included in Core Developer at no additional charge, and there is nothing separate to buy. It runs inside your Hosted Database rather than as its own product.

    It is still in Beta, though, so it is not switched on for every account yet. Confirm with Support that it is enabled for your practice before you plan reporting around it.

    How you get it depends on your access model. On an Elation-managed **Reader Account** it arrives pre-installed, and you should not run the installation script. On a **Direct Share** into your own Snowflake account, you install it yourself and point it at your own warehouse, which also means the compute it uses is billed to you rather than to Elation. See [who pays for Snowflake compute](/core-developer-pricing#who-pays-for-snowflake-compute).

    See [Elation Analyst](/articles/Elation-Analyst) for what it can and cannot answer.
  </Accordion>

  <Accordion title="Will my bill go up if my API traffic goes up?">
    No. There are no per-call, per-record, or egress charges, and no overage invoices. Provider count is what drives your cost. Full detail on [Pricing and add-ons](/core-developer-pricing).

    A few capabilities sit outside the base subscription and may carry their own cost, including the Document Signing API, the Care Gaps API, and additional daily Hosted Database refreshes. Those are requested through Support, and they are priced up front rather than metered.
  </Accordion>
</AccordionGroup>

***

**02 — ACCESS AND CREDENTIALS**

## Getting keys and keeping them working

<AccordionGroup>
  <Accordion title="Do I create my own API credentials, or does Elation issue them?">
    In the sandbox, practice admins create their own credentials from **Settings > API Access**. No ticket needed.

    In production, self-service credential management is available on request. Contact Support to have it enabled for your practice. Until then, Elation issues production credentials for you, over a secure channel.

    See [Self-Service API Credential Management](/articles/self-service-api-credential-management) for the walkthrough, and [Get started](/core-developer-access) for what has to be true before any production credential is issued.
  </Accordion>

  <Accordion title="Can I rotate a credential without taking my integration down?">
    Yes. Issue or request the replacement first, deploy it, confirm it is working, and only then revoke the old one. Both sets stay valid during the overlap, so there is no forced cutover window.

    Do not revoke first. Anything still using a revoked credential stops authenticating immediately.
  </Accordion>

  <Accordion title="I lost my client secret. Can you send it again?">
    No. The client secret is displayed once, at creation, and cannot be retrieved afterward. Elation cannot look it up either.

    Create a new credential, update your integration, then revoke the one you lost. This is also why we suggest issuing a separate credential per integration or per internal service: losing or rotating one does not disturb the rest.
  </Accordion>

  <Accordion title="Can one credential work for both REST API 2.0 and the FHIR API?">
    No. The API type is chosen when the credential is created and cannot be changed afterward, so a credential is either an Elation APIv2 credential or a FHIR R4 credential. Create one of each if you need both.

    This is the most common cause of FHIR authentication failures. A REST 2.0 client ID and secret will not mint a token on the FHIR token endpoint, and the error you get back describes a policy or scope problem rather than pointing at the credential type. If FHIR auth is failing and the same credentials work fine against REST, the credential type is the first thing to check.

    See [Service Base URLs](/articles/fhir/service-base-urls) for the FHIR endpoints and [Getting started with the FHIR API](/articles/fhir/getting-started-with-standardized-api) for registration.
  </Accordion>

  <Accordion title="My integration sent a username and password and now authentication fails.">
    The token endpoint no longer supports the Resource Owner Password Credentials flow. Stop sending the username and password, and set `grant_type` to `client_credentials`. Your client ID and secret do not change.

    See [Get Token](/articles/rest/overview/get-token).
  </Accordion>

  <Accordion title="A vendor is asking for access to my Elation data. Is that Core Developer?">
    Usually not. When a third party needs to reach your data on your behalf, that runs through Elation's partner track rather than through your own Core Developer subscription, and it is authorized by your practice in writing rather than by adding an add-on to your contract.

    Reach out to Support with the vendor's name and what they need to read or write. If Elation already has an integration with them, you may not need to build anything.
  </Accordion>
</AccordionGroup>

***

**03 — SANDBOX**

## Building before you buy

<AccordionGroup>
  <Accordion title="Do I have to buy Core Developer to get a sandbox?">
    No. The sandbox is free, and it does not require a Core Developer subscription or a particular EHR tier. It is open to current Elation customers and to organizations looking to partner with Elation.

    What it does require is an executed [API License and Usage Agreement](https://www.elationhealth.com/api-license-and-usage-agreement/). See [Get started](/core-developer-access) for the full sequence, including how to request a sandbox.
  </Accordion>

  <Accordion title="Does the sandbox come with sample patients and test data?">
    No. Your sandbox arrives as a blank replica of the EHR with only the account used to provision it. You create your own users, patient charts, appointments, and practice settings, which means your test data matches the shapes your integration actually cares about.

    Add more providers under **Settings > Manage Accounts**, the same way you would in a live practice. See [Managing user accounts](/articles/managing-user-accounts).

    Use synthetic data only. Sandbox practices are PHI-free by design.
  </Accordion>

  <Accordion title="Can I copy my sandbox setup into production when I go live?">
    No. Sandbox and production are permanently separate, and nothing moves between them in either direction. Practice configuration, users, and test charts do not transfer, and production credentials are newly generated rather than promoted.

    Plan your go-live as a fresh configuration of the production practice, not a promotion of the sandbox.
  </Accordion>

  <Accordion title="What does the sandbox validation sign-off need to include?">
    A concrete list of what you exercised: the endpoints you called, the test scenarios you ran end to end, and how your integration behaves when a call does not succeed. Cover at least `401`, `429`, and `5xx` handling, because those are the failures that show up in production rather than in a happy-path test.

    If you cannot produce that list, the build is not ready for real patient data. See [Get started](/core-developer-access).
  </Accordion>
</AccordionGroup>

***

**04 — APIS AND WEBHOOKS**

## Building against REST 2.0, FHIR, and events

<AccordionGroup>
  <Accordion title="What are the API rate limits?">
    The [API License and Usage Agreement](https://www.elationhealth.com/api-license-and-usage-agreement/) limits usage to fewer than 3 API calls per second and fewer than 150,000 calls per 24 hours. Elation reserves the right to adjust those limits. The API returns `429` when you exceed them. See [errors](/articles/rest/overview/errors).

    Two things that help in practice. Reuse an access token until it expires instead of requesting a fresh one per call, since the token endpoint is limited separately from the resource endpoints. And do not rely on a `Retry-After` header being present on every `429`. Use your own exponential backoff with jitter.
  </Accordion>

  <Accordion title="Does hitting a rate limit generate a charge?">
    No. Rate limiting is a technical protection for platform stability, not a billing mechanism. Exceeding the limit returns a `429` and never generates an invoice. Build in retry with exponential backoff and jitter — see [errors](/articles/rest/overview/errors).
  </Accordion>

  <Accordion title="Can I write data back through the FHIR API?">
    No. The FHIR R4 API supports read and search only. That is deliberate, not a configuration gap: it exists to meet the ONC Certified § 170.315(g)(10) Standardized API criterion, and no scope change, application setting, or enablement request will turn on writes.

    Anything that creates or updates data in Elation goes through REST API 2.0. Most integrations use REST 2.0 for everything and reach for FHIR only when the use case requires FHIR-standard interoperability, such as SMART on FHIR or USCDI exchange.
  </Accordion>

  <Accordion title="Why did count disappear from my list responses?">
    Because cursor-based pagination is now the default. Cursor responses return `next`, `previous`, and `results`, and they omit `count`.

    If you need the total, add an `offset` parameter to the request, for example `&offset=0`. That switches the response to offset-based pagination, which includes `count` alongside `limit` and `offset`. Either way, a single page returns at most 100 results.

    Cursor pagination is the more performant and more reliable of the two, so prefer it and track completion from `next` being null rather than from a total. See [Pagination](/articles/rest/overview/pagination).
  </Accordion>

  <Accordion title="My webhook endpoint was down. Will you resend the events I missed?">
    Yes, within limits. Retries run hourly for up to 24 hours from the original event. Only a `5xx` response or no response at all triggers a retry. A `4xx` is treated as final and is never retried, so returning `400` to an event you cannot parse discards it.

    If retries are exhausted without a `200`, the event stops and you are not notified. That is what the [Published Events API](/articles/rest/event-subscription-api/event-subscriptions/list-published-events) is for: it returns the delivery record, including the HTTP status Elation received, for every event sent to your application over the last 90 days. Reconcile against it rather than assuming delivery.

    If you find a gap older than the retry window, contact Support.

    <Info>
      **24 hours is the current retry window.** Older copies of Elation's API documentation stated 72 hours. If you are working from a bookmark or a saved PDF, check it against [Webhooks](/articles/rest/overview/webhooks).
    </Info>
  </Accordion>

  <Accordion title="Why did I receive the same webhook event more than once?">
    Delivery is at-least-once, so a delivery that succeeds on our side but whose response we never receive gets sent again. Separately, one logical change can emit more than one event for the same resource, and some background processing fires an event when nothing visible on the resource changed.

    Two consequences for your handler. Dedupe on `event_id` rather than `event_uuid`, since `event_uuid` is newer and can be absent. And make handlers idempotent per resource, not only per event: processing the same resource twice should reach the same end state rather than creating a second record.

    See [Acknowledging events](/articles/rest/overview/webhooks#acknowledging-events).
  </Accordion>

  <Accordion title="Can I poll for changes instead of subscribing to webhooks?">
    Partly, and not reliably for everything. Only two list endpoints expose a last-modified filter: `patients` and `visit_notes`. A polling loop can miss in-place edits to resources that do not expose one. That failure is silent, so you will not see an error when it happens.

    The recommended pattern is Webhooks for change detection, with the Published Events API as your reconciliation backstop. Reserve polling for `patients` and `visit_notes`.
  </Accordion>

  <Accordion title="Why do documents my integration creates come back unsigned?">
    Because API document signing is off by default. Until it is enabled for your practice, sending `signed_by` or `signed_date` returns a `400` with `"Practice does not have API signing enabled"`. Requests that omit both fields are unaffected.

    Turning it on is a paid add-on. It requires an executed BAA, and an Admin User at your practice must review and accept the [API document signing agreement](/files/api-document-signing-agreement.pdf), which covers clinical oversight and regulatory responsibility for documents signed this way. See [Pricing and add-ons](/core-developer-pricing) and [errors](/articles/rest/overview/errors#api-document-signing).

    <Warning>
      **Lab orders cannot be signed through the API.** The signing fields are ignored on lab orders rather than rejected, so the order lands as an unsigned draft and no error tells you why. Sort your signing workflow out before you build around it.
    </Warning>
  </Accordion>

  <Accordion title="Can my integration act as a specific user instead of the API account?">
    Yes, with user impersonation. By default everything your integration creates is attributed to the API service account rather than a real provider, which is rarely what you want in a chart.

    Send the `X-On-Behalf-Of` header with the numeric `id` of the user you want to act as, and the request is processed as if that user made it. Attribution then lands on that provider in the chart, the action log, and the Hosted Database.

    Your token needs the `act_as_user` scope alongside at least one resource scope, and the user has to be active and in a practice your token covers. See [User Impersonation](/articles/rest/overview/user-impersonation). This is currently in closed beta and available to select customers only, so confirm with Support that it is on for your account before you design around it.
  </Accordion>
</AccordionGroup>

***

**05 — HOSTED DATABASE**

## Querying your data in Snowflake

<AccordionGroup>
  <Accordion title="Who pays for Snowflake compute?">
    It depends on how you access the Hosted Database.

    On an Elation-managed **Reader Account**, Elation covers the Snowflake compute. Query as much as you need — there is no metering and nothing charged back to you.

    On a **Direct Share into your own Snowflake account**, you pay the compute your queries consume, because they run on your warehouse under your Snowflake contract. Elation still pays for the compute on our side that prepares and refreshes the shared data.

    Neither option changes what you pay Elation. The Reader Account keeps compute off your books. A Direct Share gives you control of the environment — roles, network policies, downstream pipelines — in exchange for owning its cost.

    If you are on a custom enterprise agreement rather than the standard subscription, check your order form.
  </Accordion>

  <Accordion title="How current is the data?">
    It refreshes once a day, either at 1am PT or 5am PT, so a given day reflects the prior day's activity in the EHR. There is no on-demand or self-service refresh, and you cannot trigger one. See [How often does my data refresh](/articles/hdb/does-my-data-refresh-in-realtime).

    Additional daily refreshes are available as a paid add-on, priced per practice. Contact Support for a quote.

    If your workflow needs data closer to real time, it belongs on [Webhooks](/articles/rest/overview/webhooks) or the REST API. The Hosted Database is built for analytics, not for driving live workflows.
  </Accordion>

  <Accordion title="My data looks stale. How do I check when it actually refreshed?">
    Hover the clock icon on any table in the Snowflake UI, or run the documented query. Both are covered in [View when your data was last refreshed](/articles/hdb/how-to-tell-when-my-data-was-last-refreshed).

    One trap is worth knowing. `hdb_last_sync` is a per-row column that records when Elation's internal store last refreshed that row from the source application. It does not tell you when your Hosted Database finished its most recent build, and it does not confirm that an individual record has landed. If you are filtering to find recent activity, filter on a business timestamp such as `creation_time` instead.

    A query that runs during the rebuild window can also see a partially built table. If the data still looks wrong after you have checked the last refresh time, contact Support with the table and what you expected.
  </Accordion>

  <Accordion title="Can I write to the Hosted Database, load my own data in, or schedule a query?">
    No to all three. Your Elation Snowflake account is a reader account. You can query the data we share, but you cannot insert, update, or delete it, load outside data into it, or create tasks, streams, procedures, or warehouses. That last restriction is what rules out scheduling a query inside the Hosted Database and emailing the results.

    See [what kind of access you get](/articles/hdb/what-kind-of-accesspermissions-do-i-get) and [Can you grant me write permissions](/articles/hdb/can-you-grant-me-write-permissions). Broad administrative roles are not granted; your role covers user and role management within your own account.

    If you need write access, scheduling, or your own pipelines, set up a Direct Share into a Snowflake account your organization owns. See [How to set up Direct Share](/articles/hdb/how-to-setup-direct-share).
  </Accordion>

  <Accordion title="What's the difference between a Reader Account and a Direct Share?">
    A Reader Account is a Snowflake account Elation owns and manages for you. You log in and query. It is the faster path and needs nothing from you beyond a login.

    A Direct Share puts the same data into a Snowflake account your organization owns, which means you control the warehouses, roles, network policies, and anything you build downstream. It is the right choice if you want to join Elation data against other sources or write transformed tables.

    You do not run both indefinitely. When you move to a Direct Share, your Reader Account stays live for 30 days and then you lose access to it, so finish your cutover inside that window. See [How to set up Direct Share](/articles/hdb/how-to-setup-direct-share) for the account details Elation needs from you.
  </Accordion>

  <Accordion title="Does the Hosted Database include Elation Billing data?">
    Only if your practice is on Elation Billing. If you are not, those tables are not created at all — they are absent from your share rather than present and empty.

    If you are on Elation Billing, clinical, operational, and billing data all sit in the same Hosted Database, which is what makes joins across the chart and the revenue cycle possible. Claims, charges, payments, ERA adjustments, and claim queues are all queryable. Browse the current tables in the [Hosted Database schema](/articles/hdb/schema).
  </Accordion>

  <Accordion title="A table or column I expected isn't in my schema.">
    Start with the [schema browser](/articles/hdb/schema) and confirm the exact name, since it is the current source of truth for every table and column.

    If it is documented but missing from your share, the usual cause is that the underlying feature is not provisioned for your practice rather than a pipeline fault. A few fields visible in the EHR are also not carried into the Hosted Database at all. Contact Support naming the table and column and we will tell you which it is.
  </Accordion>

  <Accordion title="How much notice do I get before a schema change breaks my query?">
    It depends on the class of change. Breaking changes get 30 calendar days. Behavior changes, where the schema holds but the volume of data behind it shifts, get 7 days. Purely additive changes are announced when they ship.

    Notices go to the [Hosted Database Release Notes](/articles/hdb/hdb-snowflake), which publishes RSS. Wire it into Slack or a feed reader so deprecations reach you instead of waiting to be found. See [Change management and schema versioning](/articles/hdb/change-management) for the full policy, and [Early Release](/articles/hdb/early-release) if you would rather test a change against your own pipelines before its GA date.
  </Accordion>

  <Accordion title="My API timestamps and my Hosted Database timestamps don't line up.">
    They are in different timezones. Data from the REST API should be assumed to be UTC. Data in the Hosted Database is Pacific Time, and it shifts with daylight saving.

    So an event late in the day looks like it happened on different calendar days depending on which surface you read it from, and a naive join or date filter across the two silently produces wrong counts. Normalize to one timezone before you compare. In Snowflake, `convert_timezone` does this per query, though the result does not persist.

    See [Dates](/articles/rest/overview/dates) for the API side and [What timezone is my data in](/articles/hdb/what-timezone-is-my-data-in) for the Hosted Database side, including the one column that is documented as an exception.
  </Accordion>

  <Accordion title="I'm locked out of my Snowflake account.">
    Snowflake locks a user after repeated consecutive failed logins and then clears the lock automatically after about an hour. An account admin on your side can also clear it sooner.

    The usual cause is not a person mistyping a password. It is an automated job retrying with stale credentials, which burns through the attempt count in seconds. Fix the credential in the job before you unlock, or you will lock again immediately. If you cannot get back in, contact Support.
  </Accordion>

  <Accordion title="How do I verify that Elation Analyst's answer is correct?">
    You do not need to read SQL to sanity-check an answer. Three habits do most of the work:

    1. **Read the interpretation line.** Analyst restates what it thought you asked, including the date range it chose. That is where a wrong answer usually reveals itself, and it's written in plain English.
    2. **Start with a question you already know the answer to.** Ask something you can verify against a report you already run. If it matches, you have calibrated it for the questions you can't check.
    3. **Download the CSV and spot-check a few rows.** Pull two or three patients out of the result and open their charts. Faster than auditing a query, and it catches the errors that matter.

    If a number is going somewhere consequential, like a payer submission or a board report, have someone technical read the generated SQL, or rebuild it as a saved query once and reuse it.

    <Warning>
      **Two limits to plan around.** Analyst reads the Hosted Database, so answers reflect yesterday's data, not this morning's. And it answers on demand only — you cannot schedule a question or have results emailed to you on a recurring basis. For numbers you want to watch over time, rebuild the generated SQL as a dashboard tile.
    </Warning>
  </Accordion>
</AccordionGroup>

***

**06 — SECURITY AND COMPLIANCE**

## PHI, agreements, and access control

<AccordionGroup>
  <Accordion title="Do I need a BAA?">
    Yes, for production. API access to real patient data requires an executed Business Associate Agreement, and the practice whose data you will reach must also provide written authorization and consent. No production credential is issued before both are on file, and data you retrieve has to be used and disclosed consistent with HIPAA permitted and required uses.

    The sandbox is a different matter. It is PHI-free by design, so it is gated on the API License and Usage Agreement rather than a BAA. See [Get started](/core-developer-access).
  </Accordion>

  <Accordion title="Can other Elation customers see my Hosted Database?">
    No. Your Hosted Database is a private copy of your own practice data. No other customer has access to it. Elation handles maintenance, backups, encryption, and auditing.
  </Accordion>

  <Accordion title="Do I need to allowlist Elation's IP addresses, or does Elation allowlist mine?">
    Elation does not require IP or domain allowlisting for API access. Authentication uses standard OAuth2 bearer tokens with an expiration, so calls from your infrastructure need no network-level registration with us.

    Outbound webhook traffic is the other direction, and it does originate from published, environment-specific IP ranges you may need to allow through your own firewall. Those ranges and the notice period before they change are on [Webhooks](/articles/rest/overview/webhooks#trusted-ip-addresses).
  </Accordion>

  <Accordion title="Can I restrict who reaches my Hosted Database?">
    Yes, two ways, and they stack.

    Network policies let you allow or block specific IP ranges. There is no UI for this on a reader account, so you create and manage them from a worksheet. See [Managing network policies](/articles/hdb/create-network-policies).

    Multi-factor authentication can be turned on per user from Snowflake's own settings. See [Setting up multi-factor authentication](/articles/hdb/how-to-set-up-sso).
  </Accordion>

  <Accordion title="Who at my practice can create API credentials?">
    Practice admins. Credential management lives in **Settings > API Access**, and it is available to admin users only, so a provider or staff account without administrative privileges will not see it.

    Treat credentials like a shared password for your practice's data. Store them in a secrets manager, never in email or chat, and revoke immediately if one may have been exposed. See [Self-Service API Credential Management](/articles/self-service-api-credential-management).
  </Accordion>

  <Accordion title="How do I limit what a credential can read or write?">
    With scopes, in the form `system/<resource>.<read|write>`. Assign them when you create a credential, or edit them afterward, and changes take effect immediately. A credential with no scopes assigned falls back to a global scope carrying full practice read and write, which is rarely what you want for a single-purpose integration.

    Granular scopes are currently in closed beta and available to select customers only, so confirm with Support what is enabled for your account. See [Token Scopes](/articles/rest/overview/scopes) for the format, the full resource list, and the rule that specific scopes cannot be combined with the global scope in one token request.
  </Accordion>
</AccordionGroup>

***

**07 — STAYING CURRENT**

Elation publishes RSS for both the [API 2.0 Changelog](/articles/rest/changelog/changelog) and the [Hosted Database Release Notes](/articles/hdb/hdb-snowflake). Subscribing is how you hear about new endpoints, field changes, and deprecations before they reach your integration. See [Subscribe to Elation Release Feeds](/articles/subscribe-to-release-feeds).

For pricing, access, contract questions, or anything above, raise a request at app.elationemr.com/support or contact your Customer Success Manager.

## Related articles

* [Core Developer overview](/core-developer) — what it is and who it's for
* [Pricing and add-ons](/core-developer-pricing) — cost, seat rules, and add-ons
* [Get started](/core-developer-access) — sandbox, credentials, and production access
