{"id":4022,"date":"2026-07-16T16:08:52","date_gmt":"2026-07-16T15:08:52","guid":{"rendered":"https:\/\/clubtreasurer.com\/blog\/?page_id=4022"},"modified":"2026-07-16T16:08:52","modified_gmt":"2026-07-16T15:08:52","slug":"api-developer-guide","status":"publish","type":"page","link":"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/","title":{"rendered":"Clubtreasurer Membership API \u2014 Developer Guide (v0.1)"},"content":{"rendered":"<p><strong>The Clubtreasurer Membership API lets you display and manage your club&#8217;s membership and billing data on your own website or application \u2014 member lists, membership details, invoices and balances \u2014 always live, straight from your Clubtreasurer account.<\/strong><\/p>\n<p><strong>What you can do:<\/strong><\/p>\n<ul>\n<li>List and search your members<\/li>\n<li>Read full member details, including parent\/guardian and emergency contacts<\/li>\n<li>Update a member&#8217;s contact details or section<\/li>\n<li>List your membership types and each member&#8217;s membership assignments<\/li>\n<li>List invoices and balances, for one member or your whole organisation<\/li>\n<\/ul>\n<p><strong>What you&#8217;ll need:<\/strong><\/p>\n<ul>\n<li>API credentials (a <em>Client ID<\/em> and <em>Client Secret<\/em>) issued by Clubtreasurer \u2014 contact <a href=\"mailto:support@clubtreasurer.com\"><strong>support@clubtreasurer.com<\/strong><\/a> to request them<\/li>\n<li>A server-side environment to call the API from (PHP, Node.js, Python, .NET, etc.)<\/li>\n<\/ul>\n<p>\u26a0\ufe0f <strong>Your Client Secret is a password for your club&#8217;s data. Never put it in website JavaScript, mobile apps, or anything else that runs on your users&#8217; devices<\/strong> \u2014 anyone could read it there. All API calls should be made from your own server. If you believe your secret has been exposed, contact support immediately and we will revoke and re-issue it.<\/p>\n<h2>Base URL<\/h2>\n<p>All API requests use this base URL:<\/p>\n<pre><code>https:\/\/myclubtreasurer.com\/apex\/prod\/api\/v1<\/code><\/pre>\n<p>All requests must use HTTPS. All responses are JSON.<\/p>\n<h2>Step 1 \u2014 Get an access token<\/h2>\n<p>The API uses the industry-standard <strong>OAuth 2.0 Client Credentials<\/strong> flow. You exchange your Client ID and Secret for a short-lived <em>access token<\/em>, then send that token with every API call.<\/p>\n<pre><code>POST https:\/\/myclubtreasurer.com\/apex\/prod\/oauth\/token\nContent-Type: application\/x-www-form-urlencoded\n\ngrant_type=client_credentials<\/code><\/pre>\n<p>Authenticate the request with HTTP Basic auth \u2014 username = Client ID, password = Client Secret.<\/p>\n<p><strong>curl example:<\/strong><\/p>\n<pre><code>curl -s -X POST \"https:\/\/myclubtreasurer.com\/apex\/prod\/oauth\/token\" \\\n  -u \"YOUR_CLIENT_ID:YOUR_CLIENT_SECRET\" \\\n  -d \"grant_type=client_credentials\"<\/code><\/pre>\n<p><strong>Response:<\/strong><\/p>\n<pre><code>{\n  \"access_token\": \"cfd8avMuKwcwjFNrCF-lyQ\",\n  \"token_type\": \"bearer\",\n  \"expires_in\": 3600\n}<\/code><\/pre>\n<p>Tokens are valid for <strong>1 hour<\/strong> (<code>expires_in<\/code> is in seconds). Cache the token and reuse it until it expires, then request a new one \u2014 do <strong>not<\/strong> request a new token for every API call.<\/p>\n<h2>Step 2 \u2014 Call the API<\/h2>\n<p>Send the token in the <code>Authorization<\/code> header of every request:<\/p>\n<pre><code>curl -s -H \"Authorization: Bearer YOUR_ACCESS_TOKEN\" \\\n  \"https:\/\/myclubtreasurer.com\/apex\/prod\/api\/v1\/members\/\"<\/code><\/pre>\n<p><strong>Node.js example (token + first call):<\/strong><\/p>\n<pre><code>const BASE = \"https:\/\/myclubtreasurer.com\/apex\/prod\/api\/v1\";\nconst TOKEN_URL = \"https:\/\/myclubtreasurer.com\/apex\/prod\/oauth\/token\";\n\nasync function getToken(clientId, clientSecret) {\n  const res = await fetch(TOKEN_URL, {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application\/x-www-form-urlencoded\",\n      \"Authorization\": \"Basic \" + Buffer.from(`${clientId}:${clientSecret}`).toString(\"base64\"),\n    },\n    body: \"grant_type=client_credentials\",\n  });\n  if (!res.ok) throw new Error(`Token request failed: ${res.status}`);\n  return (await res.json()).access_token;   \/\/ cache this for up to 1 hour\n}\n\nasync function listMembers(token) {\n  const res = await fetch(`${BASE}\/members\/?status=Active`, {\n    headers: { Authorization: `Bearer ${token}` },\n  });\n  if (!res.ok) throw new Error(`API call failed: ${res.status}`);\n  return (await res.json()).items;\n}<\/code><\/pre>\n<h2>Pagination<\/h2>\n<p>List endpoints return up to <strong>50 records per page<\/strong>. Page through results with <code>?offset=<\/code> and <code>?limit=<\/code>:<\/p>\n<pre><code>GET \/members\/?offset=0&amp;limit=50     \u2192 records 1\u201350\nGET \/members\/?offset=50&amp;limit=50    \u2192 records 51\u2013100<\/code><\/pre>\n<p>Every list response includes <code>\"hasMore\": true\/false<\/code> \u2014 keep increasing <code>offset<\/code> until <code>hasMore<\/code> is <code>false<\/code>. The response also includes ready-made <code>first<\/code>\/<code>next<\/code> links in the <code>links<\/code> array.<\/p>\n<p><strong>Response envelope (all list endpoints):<\/strong><\/p>\n<pre><code>{\n  \"items\": [ { ... }, { ... } ],\n  \"hasMore\": true,\n  \"limit\": 50,\n  \"offset\": 0,\n  \"count\": 50,\n  \"links\": [ ... ]\n}<\/code><\/pre>\n<h2>Endpoints<\/h2>\n<p>All dates are returned as <code>YYYY-MM-DD<\/code> strings. Field names in responses are lower-case.<\/p>\n<h3>List members<\/h3>\n<pre><code>GET \/members\/<\/code><\/pre>\n<p>Optional filters: <code>?status=Active<\/code> (member status) \u00b7 <code>?section_id=3<\/code><\/p>\n<p>Each item: <code>id<\/code>, <code>ref_id<\/code>, <code>first_name<\/code>, <code>last_name<\/code>, <code>email<\/code>, <code>telephone_num1<\/code>, <code>section_id<\/code>, <code>mem_status<\/code>, <code>gender<\/code>, <code>dob<\/code>, <code>join_date<\/code>.<\/p>\n<h3>Get one member (full detail)<\/h3>\n<pre><code>GET \/members\/{id}<\/code><\/pre>\n<p>Returns everything from the list plus: <code>email2<\/code>, <code>telephone_num2<\/code>, <code>telephone_num3<\/code>, address fields (<code>address1<\/code>\u2013<code>address3<\/code>, <code>addresstown<\/code>, <code>addresscounty<\/code>, <code>addresspostcode<\/code>, <code>addresscountry<\/code>), <code>gift_aid<\/code>, and contact records \u2014 parent\/guardian 1 (<code>pc1_first_name<\/code>, <code>pc1_last_name<\/code>, <code>pc1_email1<\/code>, <code>pc1_phone1<\/code>), parent\/guardian 2 (<code>pc2_...<\/code>), and emergency contact (<code>emc_first_name<\/code>, <code>emc_last_name<\/code>, <code>emc_phone1<\/code>).<\/p>\n<p>Returns <strong>404<\/strong> if the member does not exist in <em>your<\/em> organisation.<\/p>\n<h3>Update a member<\/h3>\n<pre><code>PUT \/members\/{id}\nContent-Type: application\/json<\/code><\/pre>\n<p><strong>Partial update<\/strong> \u2014 only the fields you include in the JSON body are changed; everything else is left untouched. Updatable fields (camelCase or snake_case both accepted):<\/p>\n<p><code>email<\/code>, <code>email2<\/code>, <code>telephoneNum1<\/code>, <code>telephoneNum2<\/code>, <code>telephoneNum3<\/code>, <code>address1<\/code>, <code>address2<\/code>, <code>address3<\/code>, <code>addressTown<\/code>, <code>addressCounty<\/code>, <code>addressPostcode<\/code>, <code>addressCountry<\/code>, <code>sectionId<\/code><\/p>\n<pre><code>curl -s -X PUT \\\n  -H \"Authorization: Bearer YOUR_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"email\": \"new.address@example.com\", \"telephoneNum1\": \"07700 900123\"}' \\\n  \"https:\/\/myclubtreasurer.com\/apex\/prod\/api\/v1\/members\/420\"<\/code><\/pre>\n<p>Responses: <strong>200<\/strong> updated \u00b7 <strong>404<\/strong> member not found in your organisation (nothing changed) \u00b7 <strong>401<\/strong> credentials no longer valid.<\/p>\n<h3>List membership types<\/h3>\n<pre><code>GET \/memberships\/<\/code><\/pre>\n<p>Your organisation&#8217;s membership types. Each item: <code>id<\/code>, <code>mem_name<\/code>, <code>mem_ref<\/code>, <code>mem_desc<\/code>, <code>billing_cycle<\/code>, <code>status<\/code>.<\/p>\n<h3>A member&#8217;s membership assignments<\/h3>\n<pre><code>GET \/members\/{id}\/memberships<\/code><\/pre>\n<p>Current (non-archived) membership assignments, newest first. Each item: <code>id<\/code>, <code>mem_map_name<\/code>, <code>mem_name<\/code>, <code>status<\/code>, <code>start_date<\/code>, <code>earliest_end_date<\/code>, <code>cancellation_date<\/code>, <code>billing_cycle<\/code>, <code>payment_term<\/code>.<\/p>\n<h3>A member&#8217;s invoices<\/h3>\n<pre><code>GET \/members\/{id}\/billing<\/code><\/pre>\n<p>Optional filters: <code>?status=<\/code> (invoice status) \u00b7 <code>?date_from=2026-01-01<\/code> \u00b7 <code>?date_to=2026-12-31<\/code> (invoice date range)<\/p>\n<p>Each item: <code>id<\/code>, <code>mem_map_id<\/code>, <code>mem_map_name<\/code>, <code>bill_from_date<\/code>, <code>bill_to_date<\/code>, <code>journal_date<\/code>, <code>due_amt<\/code>, <code>t_paid_amt<\/code>, <code>balance<\/code>, <code>inv_status<\/code>, <code>comments<\/code>.<\/p>\n<h3>All invoices for your organisation<\/h3>\n<pre><code>GET \/billing\/<\/code><\/pre>\n<p>Optional filters: <code>?member_id=<\/code> \u00b7 <code>?status=<\/code> \u00b7 <code>?date_from=<\/code> \u00b7 <code>?date_to=<\/code><\/p>\n<p>Each item adds the member&#8217;s identity: <code>member_id<\/code>, <code>first_name<\/code>, <code>last_name<\/code>, <code>ref_id<\/code>.<\/p>\n<h3>Get one invoice (full detail)<\/h3>\n<pre><code>GET \/billing\/{id}<\/code><\/pre>\n<p>Adds <code>original_amt<\/code>, <code>mem_name<\/code>, <code>billing_cycle<\/code> to the list fields. Returns <strong>404<\/strong> if the invoice is not in your organisation.<\/p>\n<h2>Status codes &amp; error handling<\/h2>\n<table>\n<thead>\n<tr>\n<th>Code<\/th>\n<th>Meaning<\/th>\n<th>What to do<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>200<\/td>\n<td>Success<\/td>\n<td>\u2014<\/td>\n<\/tr>\n<tr>\n<td>401<\/td>\n<td>Missing\/expired\/invalid token, or your API access has been revoked<\/td>\n<td>Request a new token; if it persists, contact support<\/td>\n<\/tr>\n<tr>\n<td>404<\/td>\n<td>Record doesn&#8217;t exist <strong>in your organisation<\/strong><\/td>\n<td>Check the ID; you can never read another club&#8217;s data<\/td>\n<\/tr>\n<tr>\n<td>500 \/ 555<\/td>\n<td>Unexpected server error (e.g. malformed request)<\/td>\n<td>Check your request format; contact support if it persists<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Your credentials are scoped to your organisation only \u2014 every request returns your club&#8217;s data and nothing else.<\/p>\n<h2>Good-practice checklist<\/h2>\n<ul>\n<li>\u2705 Call the API from your <strong>server<\/strong>, never from browser\/mobile code<\/li>\n<li>\u2705 Store the Client Secret in server configuration (environment variable \/ secrets store), not in source code<\/li>\n<li>\u2705 Cache the access token and reuse it for its 1-hour lifetime<\/li>\n<li>\u2705 Handle <code>401<\/code> by fetching a fresh token once, then failing gracefully<\/li>\n<li>\u2705 Use the filters (<code>status<\/code>, <code>date_from<\/code>, \u2026) rather than downloading everything and filtering locally<\/li>\n<li>\u2705 Cache responses on your side where freshness allows (e.g. member lists for a few minutes)<\/li>\n<\/ul>\n<h2>Support<\/h2>\n<ul>\n<li><strong>Credentials, questions, problems:<\/strong> <a href=\"mailto:support@clubtreasurer.com\">support@clubtreasurer.com<\/a><\/li>\n<li>Please include the approximate time of any failing request and the HTTP status code you received (never send us your Client Secret).<\/li>\n<\/ul>\n<h2>Version<\/h2>\n<table>\n<thead>\n<tr>\n<th>Version<\/th>\n<th>Date<\/th>\n<th>Notes<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>v1<\/td>\n<td>July 2026<\/td>\n<td>First release: members (read\/update), memberships, billing (read)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>The Clubtreasurer Membership API lets you display and manage your club&#8217;s membership and billing data on your own website or application \u2014 member lists, membership details, invoices and balances \u2014 always live, straight from your Clubtreasurer account. What you can do: List and search your members Read full member details, including parent\/guardian and emergency contacts&hellip;&nbsp;<a href=\"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">Clubtreasurer Membership API \u2014 Developer Guide (v0.1)<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"class_list":["post-4022","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Clubtreasurer Membership API \u2014 Developer Guide (v0.1) - Clubtreasurer Community<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Clubtreasurer Membership API \u2014 Developer Guide (v0.1) - Clubtreasurer Community\" \/>\n<meta property=\"og:description\" content=\"The Clubtreasurer Membership API lets you display and manage your club&#8217;s membership and billing data on your own website or application \u2014 member lists, membership details, invoices and balances \u2014 always live, straight from your Clubtreasurer account. What you can do: List and search your members Read full member details, including parent\/guardian and emergency contacts&hellip;&nbsp;Read More &raquo;Clubtreasurer Membership API \u2014 Developer Guide (v0.1)\" \/>\n<meta property=\"og:url\" content=\"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/\" \/>\n<meta property=\"og:site_name\" content=\"Clubtreasurer Community\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/api-developer-guide\\\/\",\"url\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/api-developer-guide\\\/\",\"name\":\"Clubtreasurer Membership API \u2014 Developer Guide (v0.1) - Clubtreasurer Community\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-07-16T15:08:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/api-developer-guide\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/api-developer-guide\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/api-developer-guide\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Clubtreasurer Membership API \u2014 Developer Guide (v0.1)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/\",\"name\":\"Clubtreasurer Community\",\"description\":\"Clubtreasurer Documentation and Member Community Forum\",\"publisher\":{\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/#organization\",\"name\":\"Clubtreasurer\",\"url\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\/\\/clubtreasurer.com\\/blog\\/wp-content\\/uploads\\/2021\\/02\\/clubtreasurer-small-300x53-1.png\",\"contentUrl\":\"https:\\/\\/clubtreasurer.com\\/blog\\/wp-content\\/uploads\\/2021\\/02\\/clubtreasurer-small-300x53-1.png\",\"width\":300,\"height\":53,\"caption\":\"Clubtreasurer\"},\"image\":{\"@id\":\"https:\\\/\\\/clubtreasurer.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Clubtreasurer Membership API \u2014 Developer Guide (v0.1) - Clubtreasurer Community","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/","og_locale":"en_GB","og_type":"article","og_title":"Clubtreasurer Membership API \u2014 Developer Guide (v0.1) - Clubtreasurer Community","og_description":"The Clubtreasurer Membership API lets you display and manage your club&#8217;s membership and billing data on your own website or application \u2014 member lists, membership details, invoices and balances \u2014 always live, straight from your Clubtreasurer account. What you can do: List and search your members Read full member details, including parent\/guardian and emergency contacts&hellip;&nbsp;Read More &raquo;Clubtreasurer Membership API \u2014 Developer Guide (v0.1)","og_url":"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/","og_site_name":"Clubtreasurer Community","twitter_card":"summary_large_image","twitter_misc":{"Estimated reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/","url":"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/","name":"Clubtreasurer Membership API \u2014 Developer Guide (v0.1) - Clubtreasurer Community","isPartOf":{"@id":"https:\/\/clubtreasurer.com\/blog\/#website"},"datePublished":"2026-07-16T15:08:52+00:00","breadcrumb":{"@id":"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/clubtreasurer.com\/blog\/api-developer-guide\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/clubtreasurer.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Clubtreasurer Membership API \u2014 Developer Guide (v0.1)"}]},{"@type":"WebSite","@id":"https:\/\/clubtreasurer.com\/blog\/#website","url":"https:\/\/clubtreasurer.com\/blog\/","name":"Clubtreasurer Community","description":"Clubtreasurer Documentation and Member Community Forum","publisher":{"@id":"https:\/\/clubtreasurer.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/clubtreasurer.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/clubtreasurer.com\/blog\/#organization","name":"Clubtreasurer","url":"https:\/\/clubtreasurer.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/clubtreasurer.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/mlhl62ah7s0d.i.optimole.com\/cb:9dk8.241e5\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/clubtreasurer.com\/blog\/wp-content\/uploads\/2021\/02\/clubtreasurer-small-300x53-1.png","contentUrl":"https:\/\/mlhl62ah7s0d.i.optimole.com\/cb:9dk8.241e5\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/clubtreasurer.com\/blog\/wp-content\/uploads\/2021\/02\/clubtreasurer-small-300x53-1.png","width":300,"height":53,"caption":"Clubtreasurer"},"image":{"@id":"https:\/\/clubtreasurer.com\/blog\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/clubtreasurer.com\/blog\/wp-json\/wp\/v2\/pages\/4022","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/clubtreasurer.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/clubtreasurer.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/clubtreasurer.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/clubtreasurer.com\/blog\/wp-json\/wp\/v2\/comments?post=4022"}],"version-history":[{"count":1,"href":"https:\/\/clubtreasurer.com\/blog\/wp-json\/wp\/v2\/pages\/4022\/revisions"}],"predecessor-version":[{"id":4023,"href":"https:\/\/clubtreasurer.com\/blog\/wp-json\/wp\/v2\/pages\/4022\/revisions\/4023"}],"wp:attachment":[{"href":"https:\/\/clubtreasurer.com\/blog\/wp-json\/wp\/v2\/media?parent=4022"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}