Skip to content
Documentation
pozyskajpacjentaDocs

API referenceEntities

Get a case study

GET/api/v1/case-studies/{slug}

Since
1.1.0
Auth
Bearer key
operationId
getCaseStudy

One published case study with before and after images, content blocks and linked treatments. A thing moved to the trash in the clinic's panel answers 404 under its address; after a restore it answers again under the same address. Responses are private to the key: Cache-Control: private, max-age=60, so cache them on your side for up to a minute.

Request

Send the clinic's key in Authorization: Bearer (see API keys).

Path parameters

  • slugstringrequired

    Slug of the case study (lower-case letters, digits, hyphens).

curl "https://app.pozyskajpacjenta.pl/api/v1/case-studies/pelna-odbudowa-usmiechu" \
  -H "Authorization: Bearer $PP_API_KEY"
import { PozyskajPacjentaClient } from "@pozyskajpacjenta/sdk";

const client = new PozyskajPacjentaClient({
  apiKey: process.env.PP_API_KEY ?? "",
  baseUrl: "https://app.pozyskajpacjenta.pl",
});

const { caseStudy } = await client.getCaseStudy("pelna-odbudowa-usmiechu");
<?php
$response = wp_remote_get(
    'https://app.pozyskajpacjenta.pl/api/v1/case-studies/pelna-odbudowa-usmiechu',
    array(
        'headers' => array( 'Authorization' => 'Bearer ' . getenv( 'PP_API_KEY' ) ),
        'timeout' => 10,
    )
);
if ( is_wp_error( $response ) ) {
    error_log( $response->get_error_message() );
    return;
}
$status = wp_remote_retrieve_response_code( $response );
$data   = json_decode( wp_remote_retrieve_body( $response ), true );

Response

200The case study.

  • caseStudyCaseStudyDetailrequired

    The case study.

    Fields (17)
    • idstringrequired

      Case study id.

    • slugstringrequired

      Slug from the case study's address.

    • pathstringrequired

      Path of the case study page.

    • titlestringrequired

      Title.

    • summarystring | null

      Short summary; null when empty.

    • beforeMediaRef | null

      Image before the treatment. Since 1.20.0: a patient's photo added with consent, only when the patient agreed to show it on the clinic's site, served from /api/case-study-photo/{id} (supports ?w= and ?f=, cached briefly). A case study added before 1.20.0 keeps its library image as before until the patient refuses or withdraws. Otherwise null.

      Fields (8)
      • urlstringrequired

        Absolute address of the file.

      • focalXinteger | null

        Horizontal focal point in percent (0 to 100) to keep when cropping, e.g. as object-position.

      • focalYinteger | null

        Vertical focal point in percent (0 to 100).

      • altstring | null

        Alternative text; null when the clinic left it empty.

      • widthintegersince 1.4.0

        Width of the original in px (library files, when known), for width/height attributes without layout shift.

      • heightintegersince 1.4.0

        Height of the original in px.

      • aiGeneratedbooleansince 1.4.0

        The image was generated by AI: label it next to the image (e.g. in a caption).

      • captionstringsince 1.4.0

        Caption to show under the image.

    • afterMediaRef | null

      Image after the treatment. Since 1.20.0: a patient's photo added with consent, only when the patient agreed to show it on the clinic's site, served from /api/case-study-photo/{id} (supports ?w= and ?f=, cached briefly). A case study added before 1.20.0 keeps its library image as before until the patient refuses or withdraws. Otherwise null.

      Fields as in MediaRef above.

    • bodyBlocksBlock[]required

      Content blocks of the case study.

      Fields of each item (4)
      • idstringrequired

        Block id, stable within the page.

      • typestringrequired

        Block type with its version, e.g. hero.v1, faq.v1.

      • propsobjectrequired

        The block's fields; their shape depends on type.

      • styleobjectsince 1.29.0

        The section's frame, beside its content. Present on the blocks of a page.

        Fields (1)
        • tonestringsince 1.29.0

          The surface the section stands on: base (the page's ground), soft (a quiet step off it), contrast (the opposite polarity: a dark band on a light theme) or brand (the theme's main colour as the ground). The clinic's site alternates base and soft down the page unless the clinic chose a tone; derive a tone's colours from the theme tokens.

          One of basesoftcontrastbrand

    • servicesRelatedService[]required

      Treatments linked to the case study (published ones only).

      Fields of each item (5)
      • idstringrequired

        Treatment id.

      • slugstringrequired

        Treatment slug.

      • pathstringrequired

        Path of the treatment page.

      • namestringrequired

        Treatment name.

      • priceFromLabelstring | null

        Price label, e.g. od 290 zł; null when the clinic shows no price.

    • publishedAtstring (date-time) | null

      Publication date, ISO 8601; null when unknown.

    • updatedAtstring (date-time)required

      Last change, ISO 8601.

    • resultsNotestring

      Since 1.21.0: the fixed note to show with every case study ("Efekty zależą od indywidualnych cech pacjenta.").

    • storyCaseStudyStory | null

      Since 1.21.0: the four-part description; null for older case studies (their text is in bodyBlocks).

      Fields (4)
      • problemstringrequired

        What the patient came with.

      • treatmentstringrequired

        What the clinic did.

      • coursestringrequired

        How the treatment went.

      • effectstringrequired

        The result.

    • pairsCaseStudyPair[]

      Since 1.21.0: every before and after pair; empty without the patient's consent.

      Fields of each item (3)
      • beforeMediaRef | nullrequired

        Before photo; null without consent.

        Fields as in MediaRef above.

      • afterMediaRef | nullrequired

        After photo; null without consent.

        Fields as in MediaRef above.

      • viewstring | nullrequired

        The view (front, profile, smile, area…); null when not set.

    • sessionsCountinteger | null

      Since 1.21.0: the number of treatment sessions; null when not given.

    • resultAfterDaysinteger | null

      Since 1.21.0: how many days after the treatment the after photo was taken; null when not given.

    • doctorSlugstring | null

      Since 1.21.0: the specialist (GET /doctors/{slug}) when published; null otherwise.

A case study (body trimmed to one block)

{
  "caseStudy": {
    "id": "cs_odbudowa",
    "slug": "pelna-odbudowa-usmiechu",
    "path": "/realizacje/pelna-odbudowa-usmiechu",
    "title": "Pełna odbudowa uśmiechu na implantach",
    "summary": "Pacjent, 58 lat, po latach unikania dentysty: sześć implantów, korony pełnoceramiczne i nowy zgryz w cztery miesiące, bez jednego dnia bez zębów.",
    "before": null,
    "after": null,
    "bodyBlocks": [
      {
        "id": "cs-odb-wyzwanie",
        "type": "rich-text.v1",
        "props": {
          "variant": "narrow",
          "heading": "Wyzwanie",
          "body": "Pan Andrzej trafił do nas po kilkunastu latach przerwy w leczeniu: brakujące zęby boczne, starte zęby przednie i zgryz obniżony tak, że zmieniał rysy twarzy. Najbardziej bał się nie zabiegów, a tego, że na czas leczenia zostanie bez zębów."
        }
      }
    ],
    "services": [],
    "publishedAt": "2026-06-20T00:00:00.000Z",
    "updatedAt": "2026-09-30T14:21:58.000Z",
    "resultsNote": "Efekty zależą od indywidualnych cech pacjenta.",
    "story": null,
    "pairs": [],
    "sessionsCount": null,
    "resultAfterDays": null,
    "doctorSlug": null
  }
}

Errors

StatusWhen
401No Authorization header
401Unknown or rotated key
404No published treatment with this slug
429Over 120 requests in this minute

Branch on the status and code, never on the Polish error text. All statuses in Errors.

401 · No Authorization header
{
  "error": "missing Authorization: Bearer <klucz z panelu Ustawienia>"
}
401 · Unknown or rotated key
{
  "error": "invalid key"
}
404 · No published treatment with this slug
{
  "error": "nie znaleziono"
}
429 · Over 120 requests in this minute
{
  "error": "przekroczono limit 120 zapytań/min"
}

Rate limit

  • 120 requests per minute per key, shared by every endpoint.
  • Every response to a valid key carries RateLimit-Remaining and RateLimit-Reset; see Rate limits.

SDK method

client.getCaseStudy(slug: string): Promise<{ caseStudy: CaseStudyDetail }>

The TypeScript tab above uses it. Install and errors: TypeScript SDK.