{"openapi":"3.0.3","servers":[{"url":"https://salesforce-mock.ngx-ramblers.org.uk","description":"Live development and test mock"}],"info":{"description":"## Try the live mock\n\n**→ [Open the operator console](/admin)** — sign in to manage teams, fixtures, API keys and writeback history.<br>\n**→ [Create or select a team](/admin)** — each team has an isolated supporter dataset.<br>\n**→ [Generate supporter fixtures](/admin?tab=generate)** — create members, affiliated members, volunteers and Wellbeing Walkers, including supporters without membership numbers.<br>\n**→ [Generate an API key](/admin?tab=tokens)** — keys are scoped to the selected team and displayed once.<br>\n**→ Use the operations below** — supply the generated `api_key` and matching `team_code` query values to retrieve supporters or test writebacks.<br>\n**→ [Inspect unsubscribe and bounce writebacks](/admin?tab=writebacks)** — review every received request and its recorded outcome.<br>\n**→ [Import or export Insight Hub data](/admin?tab=generate)** — retain spreadsheet compatibility while consumers move to the API.\n\n## Related resources\n\n**→ [Ramblers Team Emails 1.0.0 on SwaggerHub](https://app.swaggerhub.com/apis/JAMESKEARS/ramblers-group-email/1.0.0#/)** — the published interface implemented by this service.<br>\n**→ [NGX implementation programme](https://github.com/nbarrett/ngx-ramblers/issues/327)** — ordered contract, mock and consumer work.<br>\n**→ [Mock server source](https://github.com/nbarrett/ramblers-salesforce-mock)** — application code, issues and releases.<br>\n**→ [Shared contract](https://github.com/nbarrett/ramblers-salesforce-contract)** — TypeScript types, runtime validators and published-interface drift detection.<br>\n**→ [NGX Ramblers](https://github.com/nbarrett/ngx-ramblers)** — the consuming website and email platform.<br>\n**→ [Raw OpenAPI JSON](/api/openapi.json)** — the exact document rendered on this page.\n\n## About this service\n\nThis is the live development and test implementation of Ramblers Team Emails 1.0.0. It provides isolated, repeatable supporter data and auditable writebacks so API consumers can integrate without using live supporter records.","version":"1.0.0","title":"Ramblers Team Emails","contact":{"name":"Ramblers Salesforce Mock","url":"https://github.com/nbarrett/ramblers-salesforce-mock","email":"membership@ramblers.org.uk"}},"paths":{"/get_supporters":{"get":{"summary":"retrieves the current supporters for the team","operationId":"getTeamSupporters","description":"Gets a list of supporters for the team. Includes:\n- members (including payment pending and suspended)\n- affiliated members (including payment pending and suspended)\n- volunteers (only those with a current role with this team)\n- Wellbeing walkers\n","responses":{"200":{"description":"Team members, affiliated members, volunteers and wellbeing walkers returned","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/supporter"}}}}},"400":{"description":"Bad requests, typically missing field","content":{"application/json":{"schema":{"$ref":"#/components/schemas/getSupportersError"}}}},"401":{"description":"Unauthorised - either entirely or for the group requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/getSupportersError"}}}},"503":{"description":"System Unavailable Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/getSupportersError"}}}}}}},"/bounced_email":{"post":{"summary":"Updates the ramblers systems that an email address has bounced","operationId":"notifyBounce","description":"Notifies the main ramblers systems that an email has bounced\n","requestBody":{"description":"Details about the record the bounce was from","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/bouncedEmail"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateSuccess"}}}},"400":{"description":"Bad request - typically missing fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateError"}}}},"401":{"description":"Unauthorised - either entirely or for the team requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateError"}}}},"404":{"description":"Not found - We can't any record of the supporter. They may have been deleted, anonymised or merged with another record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateError"}}}},"503":{"description":"System unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateError"}}}}}}},"/unsubscribe":{"post":{"summary":"Notifies us that a supporter has unsubscribed","description":"Handles updating the supporters consent\n","requestBody":{"description":"Details about the unsubscribe request","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/unsubscribeRequest"}}}},"responses":{"200":{"description":"Success!","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateSuccess"}}}},"400":{"description":"Bad request. Typically missing fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateError"}}}},"401":{"description":"Unauthorised - either entirely or for the team requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateError"}}}},"404":{"description":"Not found - No record in the system of the supporter. Their record may have been deleted, merged or anonymised","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateError"}}}},"503":{"description":"System unavailable - Typically salesforce is being updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/supporterUpdateError"}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"query","name":"api_key"},"TeamCodeAuth":{"type":"apiKey","in":"query","name":"team_code"}},"schemas":{"supporterUpdateSuccess":{"type":"object","properties":{"responseText":{"type":"string","enum":["Update processed","Bounce logged"],"example":"Update processed"}}},"supporterUpdateError":{"type":"object","description":"Note - Errors are not final","properties":{"errorType":{"type":"string","enum":["Email not recognised for this group","Invalid email","System unavilable","Required field missing"],"example":"Email not recognised for this group"},"errorDescription":{"type":"string","example":"No record of the supporter"}}},"supporter":{"type":"object","description":"Details about a supporter associated with a group","properties":{"membershipNo":{"type":"string","example":1234567,"nullable":true},"memberRef":{"type":"string","example":1234567,"nullable":false},"contactId":{"type":"string","example":"0033z000035G6MhAAK","nullable":false},"title":{"type":"string","example":"Mx","nullable":true},"firstName":{"type":"string","example":"Bob","nullable":true},"lastName":{"type":"string","example":"Smith","nullable":false},"email":{"type":"string","format":"email","example":"example@x.ramblers.org.uk","nullable":true},"doNotEmail":{"type":"boolean","example":true,"nullable":false},"landline":{"type":"string","format":"phoneNumber","example":"0800 11 11 11","nullable":true},"mobile":{"type":"string","format":"phone number","example":"077333 3452333","nullable":true},"friendlyName":{"type":"string","example":"John","nullable":false},"membershipStatus":{"type":"string","nullable":true,"enum":["Active","Payment pending","Suspended","Lapsed","Inactive","Resigned",null],"example":"Active"},"memberType":{"type":"string","nullable":true,"enum":["Corporate Membership","Individual Life Membership","Individual Membership","Joint Life Membership","Joint Membership","Membership",null]},"membershipJoinDate":{"type":"string","format":"date","example":"2024-03-01","nullable":true},"membershipExpiry":{"type":"string","format":"date","example":"2027-04-01","nullable":true},"membershipEndDate":{"type":"string","format":"date","example":"2028-07-01","nullable":true},"teamStatus":{"type":"string","nullable":false,"description":"relationship between the team and the supporter. Could be replaced with an array of relationship values","enum":["Member","Affiliated","Volunteer","Wellbeing Walker"]},"teamRelationshipFrom":{"type":"string","format":"date","example":"2021-02-01","nullable":true},"wellbeingWalker":{"type":"boolean","example":false,"nullable":false},"walkLeader":{"type":"boolean","example":false,"nullable":false,"description":"Not necassarily with this team"},"volunteerRoles":{"type":"array","items":{"$ref":"#/components/schemas/volunteerRole"},"description":"Only contains volunteer roles for this team"},"noWalkProgram":{"type":"boolean","example":false,"nullable":false},"noCampaigning":{"type":"boolean","example":true,"nullable":false},"noSurveys":{"type":"boolean","example":false,"nullable":false},"canEmailVolunteers":{"type":"boolean","example":true,"nullable":false},"canEmailMembers":{"type":"boolean","example":false,"nullable":false},"canEmailWellbeingWalkers":{"type":"boolean","example":false,"nullable":false},"canViewMemberData":{"type":"boolean","example":true,"nullable":false},"canViewMemberDate":{"type":"boolean","example":true,"nullable":false},"emailConsent":{"type":"boolean","example":true,"nullable":false},"emailConsentLastUpdated":{"type":"string","format":"date","example":"2001-01-03","nullable":true},"postConsent":{"type":"boolean","example":true,"nullable":false},"postConsentLastUpdated":{"type":"string","format":"date","example":"2023-01-08","nullable":true},"phoneConsent":{"type":"boolean","example":true,"nullable":false},"phoneConsentLastUpdated":{"type":"string","format":"date","example":"2024-04-08","nullable":true},"emailConsentWellbeingWalks":{"type":"boolean","example":false,"nullable":false}}},"volunteerRole":{"type":"object","description":"Details about a particular role","properties":{"roleName":{"type":"string","nullable":false,"example":"Walk Leader"},"startDate":{"type":"string","format":"date","nullable":false,"example":"2024-05-17"},"displayName":{"type":"string","nullable":true,"example":"Path Inspector"},"walkLeaderStatus":{"type":"string","nullable":true,"example":"Not A Walk Leader"},"wellbeingWalksRole":{"type":"boolean","nullable":false,"example":false}}},"unsubscribeRequest":{"description":"Details about the supporter who requested to unsubscribe","type":"object","properties":{"emailAddress":{"type":"string","format":"email","nullable":false,"example":"example@x.ramblers.org.uk"},"memberRef":{"type":"string","nullable":false,"example":123435}}},"bouncedEmail":{"description":"details for handling a bounced email","type":"object","properties":{"emailAddress":{"type":"string","format":"email","nullable":false,"example":"example@y.ramblers.org.uk"},"memberRef":{"type":"string","nullable":false,"example":12345456},"bounceType":{"type":"string","enum":["Hard","Soft"],"nullable":false,"example":"Hard"}}},"getSupportersError":{"description":"Errors related to getSupporter endpoint - not final","type":"object","properties":{"errorType":{"type":"string","enum":["Unauthorised","Bad request","System unavilable"],"example":"Unauthorised"},"errorDescription":{"type":"string","example":"No record of this group"}}}}},"security":[{"ApiKeyAuth":[],"TeamCodeAuth":[]}]}