{"id":20787717,"url":"https://github.com/stemount/canopy-apidocs","last_synced_at":"2025-10-23T18:40:01.127Z","repository":{"id":79724886,"uuid":"308633052","full_name":"stemount/canopy-apidocs","owner":"stemount","description":"Canopy API Docs","archived":false,"fork":false,"pushed_at":"2020-12-23T22:52:27.000Z","size":552,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-03T20:18:06.654Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stemount.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-10-30T13:06:17.000Z","updated_at":"2025-02-19T19:51:26.000Z","dependencies_parsed_at":"2023-03-23T00:32:33.245Z","dependency_job_id":null,"html_url":"https://github.com/stemount/canopy-apidocs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stemount/canopy-apidocs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stemount%2Fcanopy-apidocs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stemount%2Fcanopy-apidocs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stemount%2Fcanopy-apidocs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stemount%2Fcanopy-apidocs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stemount","download_url":"https://codeload.github.com/stemount/canopy-apidocs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stemount%2Fcanopy-apidocs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270385467,"owners_count":24574556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T14:59:20.579Z","updated_at":"2025-10-23T18:39:56.101Z","avatar_url":"https://github.com/stemount.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Logo](/canopylogo.png \"Logo\")\n\n# API Documentation\n\n## Introduction\n\nThe Canopy API is REST based.\n\nhttps://en.wikipedia.org/wiki/Representational_state_transfer\n\nWe follow standard behaviour in terms of URL's, JSON request/response bodies where applicable and standard HTTP error codes.\n\n## Environment Details\n\nCanopy has three environments. Each environment has its own URL, which will be used by external clients in order to test functionality and then use\nit on production:\n\n- Development\n- Staging\n- Production\n\n## Requesting Your Credentials\n\nCredentials are provided on request by Canopy to yourselves. Please speak to your account manager here to obtain the details for the environments.\n\n## Requesting an API Token\n\nYou need to request an API token to make calls to the Canopy API. In order to do this you need to:\n\n1. Generate a payload using the clientId from the credentials you have been sent. The example here uses Javascript:\n\n   ```\n   function generatePayload(clientId) {\n      const now = Math.floor(Date.now() / 1000); // sec\n        const expires = now + 60 * 60;\n        var payload = {\n            iss: 'canopy.rent',\n            scope: 'request.write_only document.read_only',\n            aud: `referencing-requests/client/${clientId}/token`,\n            exp: expires,\n            iat: now\n        };\n      return payload;\n    }\n   ```\n\n2. You need to sign this with JWT (e.g. jsonwebtoken in Javascript) using the secretKey in the credentials you were sent\n\n   ```\n   const jwtKey = jwt.sign(generatePayload(config), secretKey);\n   ```\n\n   The BODY of the request should include the following\n\n   ```\n   jwtKey: jwtKey\n   ```\n\n3. The header of the request should include the apiKey from the credentials you were sent\n\n   ```\n   x-api-key: apiKey\n   ```\n\n4. Finally make a POST request with the header and body to the following endpoint:\n\n   ```\n   POST /referencing-requests/client/:clientId/token\n   ```\n\n   If the request is successful, the response body will contain the token for future API requests with an expires timestamp:\n\n   ```\n   ...\n   Response: {\n     \"success\": true,\n     \"access_token\": \"Bearer eyaasd456FFGDFGdfgdfgdfgdfg7sdyfg35htjl3bhef89y4rjkbergv-KAj-dGh0xEuZftO_Utm6dugKQ\",\n     \"expires\": 1594907203\n   }\n   ...\n   ```\n\n## Using the Authorization Token\n\nYou need to include the x-api-key and authorization token in the headers with all Canopy API endpoint requests.\n\n```\nx-api-key: key\nAuthorization: token\n```\n\nThis token has an expiryTime of 20 minutes, after which you will receive an authorization error, and you will then need to retrieve a new token.\n\n## Refresh Secret Key\n\nRequires authorization. This endpoint may be called to change current `secretKey` and get back freshly generated one. Accepts currently active `secretKey` in request body. After receiving successful response with new `secretKey`, previous `secretKey` becomes stale and should not be used for generation `jwtKey`.\n\n```\nPOST /referencing-requests/client/refresh\n```\n\nRequest body:\n\n```\nsecretKey: string;\n```\n\nResponse body:\n\n```\nsecretKey: string;\n```\n\n## Prefill User's Rent Passport with Existing Data\n\nIf you already have some user information, such as identity, income and (or) rent, you can send it Canopy, so we will prefill the user's Rent Passport with provided data.\n\n### Set Identity\n\n```\nPOST /referencing-requests/client-user-data/set-identity\n```\n\nRequest Body\n\n```\nemail: string (required)\nfirstName: string (required)\nmiddleName: string (optional)\nlastName: string (required)\ndateOfBirth: string (required, date format YYYY-MM-DD)\nphone: string (required)\naddresses: [ /* an array of addresses, each of them has the following format */\n  {\n    startDate: string (required)\n    flat: string (optional)\n    houseNumber: string (required if houseName is not present)\n    houseName: string (required of houseNumber is not present)\n    street: string (required)\n    countryCode: enum (required) - see the list of possible values below\n    county: string (optional)\n    town: string (required)\n    postCode: string (required),\n    line1: string (optional)\n    line2: string (optional)\n    line3: string (optional)\n  }\n]\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand the list of values for the \u003ccode\u003ecountryCode\u003c/code\u003e field in the above request body\n  \u003c/summary\u003e\n  \u003cbr\u003e\n  \u003cp\u003eBelow you can see the list of countries which Canopy can handle. Each item has 2 fields: \u003ccode\u003evalue\u003c/code\u003e and \u003ccode\u003elabel\u003c/code\u003e.\n  You should pass only \u003ccode\u003evalue\u003c/code\u003e parameter to the \u003ccode\u003ecountryCode\u003c/code\u003e field from the above request body.\u003c/p\u003e\n\n  \u003cp\u003eFor example, if the country is United Kingdom, then \u003ccode\u003ecountryCode\u003c/code\u003e field should take \"GB\" value, i.e \u003ccode\u003ecountryCode: \"GB\"\u003c/code\u003e.\n  \u003c/p\u003e\n  \u003cpre\u003e\n{value: \"GB\", label: \"United Kingdom\"},\n{value: \"AF\", label: \"Afghanistan\"},\n{value: \"AX\", label: \"Åland Islands\"},\n{value: \"AL\", label: \"Albania\"},\n{value: \"DZ\", label: \"Algeria\"},\n{value: \"AS\", label: \"American Samoa\"},\n{value: \"AD\", label: \"Andorra\"},\n{value: \"AO\", label: \"Angola\"},\n{value: \"AI\", label: \"Anguilla\"},\n{value: \"AQ\", label: \"Antarctica\"},\n{value: \"AG\", label: \"Antigua and Barbuda\"},\n{value: \"AR\", label: \"Argentina\"},\n{value: \"AM\", label: \"Armenia\"},\n{value: \"AW\", label: \"Aruba\"},\n{value: \"AU\", label: \"Australia\"},\n{value: \"AT\", label: \"Austria\"},\n{value: \"AZ\", label: \"Azerbaijan\"},\n{value: \"BS\", label: \"Bahamas\"},\n{value: \"BH\", label: \"Bahrain\"},\n{value: \"BD\", label: \"Bangladesh\"},\n{value: \"BB\", label: \"Barbados\"},\n{value: \"BY\", label: \"Belarus\"},\n{value: \"BE\", label: \"Belgium\"},\n{value: \"BZ\", label: \"Belize\"},\n{value: \"BJ\", label: \"Benin\"},\n{value: \"BM\", label: \"Bermuda\"},\n{value: \"BT\", label: \"Bhutan\"},\n{value: \"BO\", label: \"Bolivia, Plurinational State of\"},\n{value: \"BQ\", label: \"Bonaire, Sint Eustatius and Saba\"},\n{value: \"BA\", label: \"Bosnia and Herzegovina\"},\n{value: \"BW\", label: \"Botswana\"},\n{value: \"BV\", label: \"Bouvet Island\"},\n{value: \"BR\", label: \"Brazil\"},\n{value: \"IO\", label: \"British Indian Ocean Territory\"},\n{value: \"BN\", label: \"Brunei Darussalam\"},\n{value: \"BG\", label: \"Bulgaria\"},\n{value: \"BF\", label: \"Burkina Faso\"},\n{value: \"BI\", label: \"Burundi\"},\n{value: \"KH\", label: \"Cambodia\"},\n{value: \"CM\", label: \"Cameroon\"},\n{value: \"CA\", label: \"Canada\"},\n{value: \"CV\", label: \"Cape Verde\"},\n{value: \"KY\", label: \"Cayman Islands\"},\n{value: \"CF\", label: \"Central African Republic\"},\n{value: \"TD\", label: \"Chad\"},\n{value: \"CL\", label: \"Chile\"},\n{value: \"CN\", label: \"China\"},\n{value: \"CX\", label: \"Christmas Island\"},\n{value: \"CC\", label: \"Cocos (Keeling) Islands\"},\n{value: \"CO\", label: \"Colombia\"},\n{value: \"KM\", label: \"Comoros\"},\n{value: \"CG\", label: \"Congo\"},\n{value: \"CD\", label: \"Congo, the Democratic Republic of the\"},\n{value: \"CK\", label: \"Cook Islands\"},\n{value: \"CR\", label: \"Costa Rica\"},\n{value: \"CI\", label: \"Côte d'Ivoire\"},\n{value: \"HR\", label: \"Croatia\"},\n{value: \"CU\", label: \"Cuba\"},\n{value: \"CW\", label: \"Curaçao\"},\n{value: \"CY\", label: \"Cyprus\"},\n{value: \"CZ\", label: \"Czech Republic\"},\n{value: \"DK\", label: \"Denmark\"},\n{value: \"DJ\", label: \"Djibouti\"},\n{value: \"DM\", label: \"Dominica\"},\n{value: \"DO\", label: \"Dominican Republic\"},\n{value: \"EC\", label: \"Ecuador\"},\n{value: \"EG\", label: \"Egypt\"},\n{value: \"SV\", label: \"El Salvador\"},\n{value: \"GQ\", label: \"Equatorial Guinea\"},\n{value: \"ER\", label: \"Eritrea\"},\n{value: \"EE\", label: \"Estonia\"},\n{value: \"ET\", label: \"Ethiopia\"},\n{value: \"FK\", label: \"Falkland Islands (Malvinas)\"},\n{value: \"FO\", label: \"Faroe Islands\"},\n{value: \"FJ\", label: \"Fiji\"},\n{value: \"FI\", label: \"Finland\"},\n{value: \"FR\", label: \"France\"},\n{value: \"GF\", label: \"French Guiana\"},\n{value: \"PF\", label: \"French Polynesia\"},\n{value: \"TF\", label: \"French Southern Territories\"},\n{value: \"GA\", label: \"Gabon\"},\n{value: \"GM\", label: \"Gambia\"},\n{value: \"GE\", label: \"Georgia\"},\n{value: \"DE\", label: \"Germany\"},\n{value: \"GH\", label: \"Ghana\"},\n{value: \"GI\", label: \"Gibraltar\"},\n{value: \"GR\", label: \"Greece\"},\n{value: \"GL\", label: \"Greenland\"},\n{value: \"GD\", label: \"Grenada\"},\n{value: \"GP\", label: \"Guadeloupe\"},\n{value: \"GU\", label: \"Guam\"},\n{value: \"GT\", label: \"Guatemala\"},\n{value: \"GG\", label: \"Guernsey\"},\n{value: \"GN\", label: \"Guinea\"},\n{value: \"GW\", label: \"Guinea-Bissau\"},\n{value: \"GY\", label: \"Guyana\"},\n{value: \"HT\", label: \"Haiti\"},\n{value: \"HM\", label: \"Heard Island and McDonald Islands\"},\n{value: \"VA\", label: \"Holy See (Vatican City State)\"},\n{value: \"HN\", label: \"Honduras\"},\n{value: \"HK\", label: \"Hong Kong\"},\n{value: \"HU\", label: \"Hungary\"},\n{value: \"IS\", label: \"Iceland\"},\n{value: \"IN\", label: \"India\"},\n{value: \"ID\", label: \"Indonesia\"},\n{value: \"IR\", label: \"Iran, Islamic Republic of\"},\n{value: \"IQ\", label: \"Iraq\"},\n{value: \"IE\", label: \"Ireland\"},\n{value: \"IM\", label: \"Isle of Man\"},\n{value: \"IL\", label: \"Israel\"},\n{value: \"IT\", label: \"Italy\"},\n{value: \"JM\", label: \"Jamaica\"},\n{value: \"JP\", label: \"Japan\"},\n{value: \"JE\", label: \"Jersey\"},\n{value: \"JO\", label: \"Jordan\"},\n{value: \"KZ\", label: \"Kazakhstan\"},\n{value: \"KE\", label: \"Kenya\"},\n{value: \"KI\", label: \"Kiribati\"},\n{value: \"KP\", label: \"Korea, Democratic People's Republic of\"},\n{value: \"KR\", label: \"Korea, Republic of\"},\n{value: \"KW\", label: \"Kuwait\"},\n{value: \"KG\", label: \"Kyrgyzstan\"},\n{value: \"LA\", label: \"Lao People's Democratic Republic\"},\n{value: \"LV\", label: \"Latvia\"},\n{value: \"LB\", label: \"Lebanon\"},\n{value: \"LS\", label: \"Lesotho\"},\n{value: \"LR\", label: \"Liberia\"},\n{value: \"LY\", label: \"Libya\"},\n{value: \"LI\", label: \"Liechtenstein\"},\n{value: \"LT\", label: \"Lithuania\"},\n{value: \"LU\", label: \"Luxembourg\"},\n{value: \"MO\", label: \"Macao\"},\n{value: \"MK\", label: \"Macedonia, the former Yugoslav Republic of\"},\n{value: \"MG\", label: \"Madagascar\"},\n{value: \"MW\", label: \"Malawi\"},\n{value: \"MY\", label: \"Malaysia\"},\n{value: \"MV\", label: \"Maldives\"},\n{value: \"ML\", label: \"Mali\"},\n{value: \"MT\", label: \"Malta\"},\n{value: \"MH\", label: \"Marshall Islands\"},\n{value: \"MQ\", label: \"Martinique\"},\n{value: \"MR\", label: \"Mauritania\"},\n{value: \"MU\", label: \"Mauritius\"},\n{value: \"YT\", label: \"Mayotte\"},\n{value: \"MX\", label: \"Mexico\"},\n{value: \"FM\", label: \"Micronesia, Federated States of\"},\n{value: \"MD\", label: \"Moldova, Republic of\"},\n{value: \"MC\", label: \"Monaco\"},\n{value: \"MN\", label: \"Mongolia\"},\n{value: \"ME\", label: \"Montenegro\"},\n{value: \"MS\", label: \"Montserrat\"},\n{value: \"MA\", label: \"Morocco\"},\n{value: \"MZ\", label: \"Mozambique\"},\n{value: \"MM\", label: \"Myanmar\"},\n{value: \"NA\", label: \"Namibia\"},\n{value: \"NR\", label: \"Nauru\"},\n{value: \"NP\", label: \"Nepal\"},\n{value: \"NL\", label: \"Netherlands\"},\n{value: \"NC\", label: \"New Caledonia\"},\n{value: \"NZ\", label: \"New Zealand\"},\n{value: \"NI\", label: \"Nicaragua\"},\n{value: \"NE\", label: \"Niger\"},\n{value: \"NG\", label: \"Nigeria\"},\n{value: \"NU\", label: \"Niue\"},\n{value: \"NF\", label: \"Norfolk Island\"},\n{value: \"MP\", label: \"Northern Mariana Islands\"},\n{value: \"NO\", label: \"Norway\"},\n{value: \"OM\", label: \"Oman\"},\n{value: \"PK\", label: \"Pakistan\"},\n{value: \"PW\", label: \"Palau\"},\n{value: \"PS\", label: \"Palestinian Territory, Occupied\"},\n{value: \"PA\", label: \"Panama\"},\n{value: \"PG\", label: \"Papua New Guinea\"},\n{value: \"PY\", label: \"Paraguay\"},\n{value: \"PE\", label: \"Peru\"},\n{value: \"PH\", label: \"Philippines\"},\n{value: \"PN\", label: \"Pitcairn\"},\n{value: \"PL\", label: \"Poland\"},\n{value: \"PT\", label: \"Portugal\"},\n{value: \"PR\", label: \"Puerto Rico\"},\n{value: \"QA\", label: \"Qatar\"},\n{value: \"RE\", label: \"Réunion\"},\n{value: \"RO\", label: \"Romania\"},\n{value: \"RU\", label: \"Russian Federation\"},\n{value: \"RW\", label: \"Rwanda\"},\n{value: \"BL\", label: \"Saint Barthélemy\"},\n{value: \"SH\", label: \"Saint Helena, Ascension and Tristan da Cunha\"},\n{value: \"KN\", label: \"Saint Kitts and Nevis\"},\n{value: \"LC\", label: \"Saint Lucia\"},\n{value: \"MF\", label: \"Saint Martin (French part)\"},\n{value: \"PM\", label: \"Saint Pierre and Miquelon\"},\n{value: \"VC\", label: \"Saint Vincent and the Grenadines\"},\n{value: \"WS\", label: \"Samoa\"},\n{value: \"SM\", label: \"San Marino\"},\n{value: \"ST\", label: \"Sao Tome and Principe\"},\n{value: \"SA\", label: \"Saudi Arabia\"},\n{value: \"SN\", label: \"Senegal\"},\n{value: \"RS\", label: \"Serbia\"},\n{value: \"SC\", label: \"Seychelles\"},\n{value: \"SL\", label: \"Sierra Leone\"},\n{value: \"SG\", label: \"Singapore\"},\n{value: \"SX\", label: \"Sint Maarten (Dutch part)\"},\n{value: \"SK\", label: \"Slovakia\"},\n{value: \"SI\", label: \"Slovenia\"},\n{value: \"SB\", label: \"Solomon Islands\"},\n{value: \"SO\", label: \"Somalia\"},\n{value: \"ZA\", label: \"South Africa\"},\n{value: \"GS\", label: \"South Georgia and the South Sandwich Islands\"},\n{value: \"SS\", label: \"South Sudan\"},\n{value: \"ES\", label: \"Spain\"},\n{value: \"LK\", label: \"Sri Lanka\"},\n{value: \"SD\", label: \"Sudan\"},\n{value: \"SR\", label: \"Suriname\"},\n{value: \"SJ\", label: \"Svalbard and Jan Mayen\"},\n{value: \"SZ\", label: \"Swaziland\"},\n{value: \"SE\", label: \"Sweden\"},\n{value: \"CH\", label: \"Switzerland\"},\n{value: \"SY\", label: \"Syrian Arab Republic\"},\n{value: \"TW\", label: \"Taiwan, Province of China\"},\n{value: \"TJ\", label: \"Tajikistan\"},\n{value: \"TZ\", label: \"Tanzania, United Republic of\"},\n{value: \"TH\", label: \"Thailand\"},\n{value: \"TL\", label: \"Timor-Leste\"},\n{value: \"TG\", label: \"Togo\"},\n{value: \"TK\", label: \"Tokelau\"},\n{value: \"TO\", label: \"Tonga\"},\n{value: \"TT\", label: \"Trinidad and Tobago\"},\n{value: \"TN\", label: \"Tunisia\"},\n{value: \"TR\", label: \"Turkey\"},\n{value: \"TM\", label: \"Turkmenistan\"},\n{value: \"TC\", label: \"Turks and Caicos Islands\"},\n{value: \"TV\", label: \"Tuvalu\"},\n{value: \"UG\", label: \"Uganda\"},\n{value: \"UA\", label: \"Ukraine\"},\n{value: \"AE\", label: \"United Arab Emirates\"},\n{value: \"US\", label: \"United States\"},\n{value: \"UM\", label: \"United States Minor Outlying Islands\"},\n{value: \"UY\", label: \"Uruguay\"},\n{value: \"UZ\", label: \"Uzbekistan\"},\n{value: \"VU\", label: \"Vanuatu\"},\n{value: \"VE\", label: \"Venezuela, Bolivarian Republic of\"},\n{value: \"VN\", label: \"Vietnam\"},\n{value: \"VG\", label: \"Virgin Islands, British\"},\n{value: \"VI\", label: \"Virgin Islands, U.S.\"},\n{value: \"WF\", label: \"Wallis and Futuna\"},\n{value: \"EH\", label: \"Western Sahara\"},\n{value: \"YE\", label: \"Yemen\"},\n{value: \"ZM\", label: \"Zambia\"},\n{value: \"ZW\", label: \"Zimbabwe\"}\n  \u003c/pre\u003e\n\u003c/details\u003e\n\nResponse Body\n\n```\nemail: string;\nfirstName: string;\nlastName: string;\ndateOfBirth: ISODate;\nphone: string;\naddresses - array of provided addresses;\nmiddleName: string (optional);\n```\n\n### Set Income\n\n```\nPOST /referencing-requests/client-user-data/set-income\n```\n\nRequest Body\n\n```\nemail: string, (required);\ndata: { /* required field with the following structure: */\n  income: required array of income objects, minimum 1 item;\n}\n```\n\nThe objects inside the \"income\" array from the above request body can be any of the following:\n\n- \"EMPLOYED\" type\n\n  ```\n  incomeSource: \"EMPLOYED\", required\n  annualSalary: integer, required\n  paymentFrequency: string, one of [\"MONTHLY\", \"TWO_WEEKLY\", \"WEEKLY\"], required\n  additionalInfo: string, optional\n  employment: {\n    companyName: string, required\n    jobTitle: string, required\n    employmentStatus: string, one of [\"FULL_TIME\", \"PART_TIME\"], required\n    employmentBasis: string, one of [\"PERMANENT\", \"CONTRACT\"], required\n    startDate: string, date format YYYY-MM-DD, required\n  }\n  ```\n\n- \"SELF_EMPLOYED\" type\n\n  ```\n  incomeSource: \"SELF_EMPLOYED\", required\n  annualSalary: integer, required\n  paymentFrequency: string, one of [\"MONTHLY\", \"TWO_WEEKLY\", \"WEEKLY\"], required\n  additionalInfo: string, optional,\n  employment: {\n    incomeName: string, required\n    jobTitle: string, required\n    startDate: string, date format YYYY-MM-DD, required\n  }\n  ```\n\n- \"STUDENT\" type\n\n  ```\n    incomeSource: \"STUDENT\", required\n    annualSalary: integer, required\n    paymentFrequency: string, one of [\"MONTHLY\", \"TWO_WEEKLY\", \"WEEKLY\", \"OTHER\"], required\n    additionalInfo: string, optional,\n    employment: {\n      educationalInstitutionName: string, required\n      grantsAvailability: boolean, required\n      startDate: string, date format YYYY-MM-DD, required if grantsAvailability is true\n    }\n  ```\n\n- \"RETIRED\", \"UNEMPLOYED\", \"BENEFITS\" or \"OTHER\" type\n  ```\n    incomeSource: string, [\"RETIRED\", \"UNEMPLOYED\", \"BENEFITS\", \"OTHER\"], required\n    annualSalary: integer, required\n    paymentFrequency: string, [\"MONTHLY\", \"TWO_WEEKLY\", \"WEEKLY\", \"OTHER\"], required\n    additionalInfo: string, optional,\n    employment: {\n      incomeName: string, required\n      description: string, required\n      startDate: string, date format YYYY-MM-DD, required\n    }\n  ```\n\nResponse Body\n\n```\nclientId: uuid;\nemail: string;\nincome: [ /* array of objects, each of them has the following structure */\n  {\n    incomeSource: string, one of [\"EMPLOYED\", \"SELF_EMPLOYED\", \"STUDENT\", \"RETIRED\", \"UNEMPLOYED\", \"BENEFITS\", \"OTHER\"];\n    annualSalary: integer;\n    paymentFrequency: string, one of [\"MONTHLY\", \"TWO_WEEKLY\", \"WEEKLY\", \"OTHER\"];\n    additionalInfo: string, optional;\n    employment: object, can take one of the schemas below;\n  }\n]\n```\n\nThe \"employment\" field from the above response can be one of the following:\n\n- ```\n  Employed {\n    companyName: string;\n    jobTitle: string;\n    employmentStatus: string, one of [\"FULL_TIME\", \"PART_TIME\"];\n    employmentBasis: string, one of [\"PERMANENT\", \"CONTRACT\"];\n    startDate: Date;\n  }\n  ```\n\n- ```\n  SelfEmployed {\n    incomeName: string;\n    jobTitle: string;\n    startDate: Date;\n  }\n  ```\n\n- ```\n  Student {\n    educationalInstitutionName: string;\n    grantsAvailability: boolean;\n    startDate?: Date;\n  }\n  ```\n\n- ```\n  Retired {\n    incomeName: string;\n    description: string;\n    startDate: Date;\n  }\n  ```\n\n- ```\n  Unemployed {\n    incomeName: string;\n    description: string;\n    startDate: Date;\n  }\n  ```\n\n- ```\n  Benefits {\n    incomeName: string;\n    description: string;\n    startDate: Date;\n  }\n  ```\n\n- ```\n  Other {\n    incomeName: string;\n    description: string;\n    startDate: Date;\n  }\n  ```\n\n### Set Rent\n\n```\nPOST /referencing-requests/client-user-data/set-rent\n```\n\nRequest Body\n\n```\nemail: string, required,\ndata: {\n  homeowner: boolean, required\n  rentsDuringLastYear: boolean, required\n  rents: [ required if rentsDuringLastYear is true, minimum 1 item\n    {\n      name: string, required\n      paymentFrequency: string, one of [\"MONTHLY\", \"TWO_WEEKLY\", \"WEEKLY\", \"OTHER\"], required\n      rentPaymentAmount: integer, required\n      rentPaidTo: string, required\n    }\n  ]\n}\n```\n\nResponse Body\n\n```\nclientId: uuid;\nemail: string;\nrentData: {\n  homeowner: boolean;\n  rentsDuringLastYear: boolean;\n  rents: [ /* optional field */\n    {\n      name: string;\n      paymentFrequency: string, one of [\"MONTHLY\", \"TWO_WEEKLY\", \"WEEKLY\", \"OTHER\"];\n      rentPaymentAmount: integer;\n      rentPaidTo: string;\n    }\n  ];\n```\n\n## Referencing Endpoints\n\nInside the Canopy system, there are 3 main entities: company, branch and agent. All communications between the agents and renters happen on the branch level, not on the company level. It means that each company must have at least one branch (let’s call it *default*), so all existing or new agents should belong to the particular branch(es) in order to work with the potential or actual renters. For example, if the agent belongs to **Branch 1** and this agent sends the invite to the potential renter, actually the invite is sent from **Branch 1**, not directly from the agent or **Company**.\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"/company-branch.svg\" /\u003e\u003c/p\u003e\n\nTherefore, in order to work with us, we create a Company and the default Branch for you at the very beginning. On the basic level, it’s enough for the correct workflow. There are the following possible scenarios:\n- **You work on the Company level and don’t have such concept as Branch**: \n\u003c/br\u003e In that case, there is no need to Link your branches with Canopy branches. For all the internal interactions, we will use the default branch (**Branch 1**) created for you.\n- **Beside the Company, you have one Branch as well so you work on the Branch level as we do**:\n\u003c/br\u003e In that case, you can link your single branch with our default branch, but it’s also an optional step. Anyway, we will use the default **Branch 1** for our internal communication with the renters.\n- **Beside the Company, you have several branches so you work on the Branch level as we do:**\n\u003c/br\u003eThis is basically the same approach which is used inside the Canopy system. In order to request a reference for the particular renter, you can either:\n  - Use the default branch, which is already created in the Canopy\n  - Preliminary create an additional branches (Branch 2, Branch 3, …, Branch N) in Canopy system and then link/map them with your own branches. \n\n  After that, at the moment of requesting a reference from Canopy for the user, you can specify the branch to which this reference should be attached. But again, this step of branch mapping is an optional step. If you don’t want to link anything, just skip the Branch Linking step so that we will always use the default branch for the internal interactions with renter.\n\n\n### Get the List of Branches and Connections\n\nThe endpoint below returns the list of canopy branches associated with `clientId` and connections with client branches. Canopy branch might be linked with some client branch, in this case `clientBranchId` value will contain id of the client branch. If canopy branch linked with multiple client branches, then same canopy branch will appear in the list multiple times with different `clientBranchId`. If canopy branch is not linked to any client branch, then `clientBranchId` will be equal to `null`.\n\n```\nGET /referencing-requests/client/:clientId/branches-list\n```\n\nParameters:\n\n```\nclientId: your client reference\n```\n\nResponse body:\n\n```\n/* an array of branches, each of them has the following structure */\n\n\"branches\": [\n  {\n    \"canopyBranchId\": string — id of the Canopy branch,\n    \"clientBranchId\": string or null — id of the client's branch that is linked with this canopy branch, if equals null than this canopy branch is not linked with any client branch\n    \"branchName\": string — the name of the Canopy branch,\n    \"branchAddress\": { - branch address entity\n      \"id\": string, - id of the branch address\n      \"line1\": string,\n      \"line2\": string,\n      \"line3\": string,\n      \"street\": string,\n      \"town\": string,\n      \"postCode\": string,\n      \"countryCode\": string,\n      \"flat\": string,\n      \"district\": string,\n      \"houseNumber\": string,\n      \"houseName\": string\n    },\n  }\n]\n```\n\n### Link Branch\n\nThe endpoint below links existing Canopy branch with client's branch. This operation is required for [referencing request](https://github.com/insurestreetltd/canopy-apidocs/tree/master#request-referencing). `clientBranchId` should be unique, so there can be only one connection with specific client branch. `canopyBranchId` can be used in multiple connections, so there can be multiple connections between single canopy branch and multiple client's branches.\n\n```\nPOST /referencing-requests/client/:clientId/link-branch\n```\n\nParameters:\n\n```\nclientId: your client reference\n```\n\nRequest body:\n\n```\ncanopyBranchId: string - id of the Canopy branch, you can get list of possible branches using GET /bracnhes-list endpoint\nclientBranchId: string - id of the branch in the client's system, it can be any string of uuid format and should be unique\n```\n\nSuccessful response body:\n\n```\n\"canopyBranchId\": string — id of the Canopy branch\n\"clientBranchId\": string — id of the branch in the client's system\n\"branchName\": string — name of the Canopy branch\n\"branchAddress\": { - branch address entity\n  \"id\": string,\n  \"line1\": string,\n  \"line2\": string,\n  \"line3\": string,\n  \"street\": string,\n  \"town\": string,\n  \"postCode\": string,\n  \"countryCode\": string,\n  \"flat\": string,\n  \"district\": string,\n  \"houseNumber\": string,\n  \"houseName\": string\n}\n```\n\nUnsuccessful response body:\n\n```\n/* If requested Canopy branch is not associated with client's agency you’ll get the following error */\n\n\"success\": false,\n\"requestId\" — the identifier of the request,\n\"error\": {\n  \"status\": 400,\n  \"type\" — error type,\n  \"message\" — “Requested canopy branch is not associated with the client's agency”,\n}\n```\n\n### Delete Branch Mapping\n\nThe endpoints below deletes existing branch mapping between Canopy branch and client branch:\n\n```\nDELETE /referencing-requests/client/:clientId/branch-mapping/:clientBranchId\n```\n\nParameters:\n\n```\nclientId: your client reference\nclientBranchId: id of the branch linked with the Canopy branch\n```\n\nResponse body:\n\n```\nclientBranchId: string\n```\n\n### Request Referencing\n\nThis endpoint creates new referencing request.\n\n```\nPOST /referencing-requests/client/:clientId/request\n```\n\nParameters:\n\n```\nclientId: your client reference\n```\n\nRequest body:\n\n```\nemail: string (required),\nfirstName: string (optional),\nmiddleName: string (optional),\nlastName: string (optional),\ncallbackUrl: string (required) - URL to which Canopy will send PDF Report,\nrequestType: enum (required) - one of [RENTER_SCREENING, GUARANTOR_SCREENING],\nitemType: enum (required) - one of [INSTANT, FULL],\ntitle: string (optional) - it's a title used before a surname or full name,\nphone: string (optional),\nbranchId: string (optional) - clientBranchId that is connected to any canopy branch, you can get list of created connections using GET /bracnhes-list endpoint, if there's no connection created with such branchId then this API call will return 404 error, new connection can be created using POST /link-branch endpoint, if no branchId is passed than default branch will be used for the referencing request\nclientReferenceId: string (optional) - this is unique identifier on the client's side\n```\n\nIf a referencing request is registered successfully you will receive the following response:\n\n```\n\"requestId\" - the identifier of the request,\n\"success\": true\n\"canopyReferenceId\"\n```\n\nIf there was an `authentication` error while handling a new request, then you will receive the following:\n\n```\n\"success\": false,\n\"requestId\" - the identifier of the request,\n\"error\": {\n  \"status\": 401,\n  \"type\" - error type,\n  \"message\" - error message\n}\n```\n\nIf there was a `validation` error while handling a new request, then you will receive the following:\n\n```\n\"success\": false,\n\"requestId\" - the identifier of the request,\n\"error\": {\n  \"status\": 400,\n  \"type\" - error type,\n  \"message\" - error message,\n  \"errors\": [] - an array of error objects, each of them has the following structure:\n    {\n      \"type\" - error type,\n      \"path\" - error path,\n      \"message\" - error message\n    }\n}\n```\n\n### Rent Passport Retrieval\n\nOnce referencing has been completed by the renter in the Canopy mobile application, an update message will be sent to the `callbackUrl` provided at the moment of referencing request. This message will have the following structure:\n\n```\nclientReferenceId: string,\ncanopyReferenceId: uuid,\ndocument: {\n  documentType: enum - one of [0, 1]; /* 0 means INSTANT screening type, 1 means FULL screening type */\n  url: `/referencing-requests/client/:clientId/documents/:documentId`,\n  maxRent: number,\n  status: string,\n  title: enum - one of [INSTANT, FULL]\n}\n```\n\nTo retrieve a PDF Rent Passport after successful referencing completion, you can use the `url` field from the above response:\n\n```\nGET /referencing-requests/client/:clientId/documents/:documentId\n```\n\nParameters:\n\n```\nclientId: your client reference\ndocumentId: the ID of the document returned from the document update\n```\n\nResponse:\n\nThe PDF will be included in the response body with the filename specified in the header as follows:\n\n```\ncontent-type: application/pdf\ncontent-disposition: attachment; filename='9e6222ee-312b-2297-a03a-07700363a6b6_FULL.pdf'\n```\n\n### Get Intermediate PDF Report\n\nGet Screening Results of the renter, even if Passport is not completed. When you receive notifications that some of the Renter Passports sections were updated, you can call and get a PDF Report with current state. For example it is useful when renter should provide FULL referencing, but you wish to see INSTANT screening results as soon as it is completed and not wait while full screening will be passed.\n\n```\nGET /referencing-requests/client/:clientId/rent-passport/:canopyReferenceId\n```\n\nParameters:\n\n```\nclientId – your client reference,\ncanopyReferenceId – the id of registered request on the Canopy side,\n\nAlso, this endpoint may accept ?format=json query param to return RP in json format, in other cases returns pdf.\n```\n\n## Webhooks Endpoints\n\n### Register Webhook\n\nThe endpoint below registers the webhook with the appropriate type in Canopy system. After that, Rent Passport updates will be sent to the specified callback url.\n\n```\nPOST /referencing-requests/client/:clientId/webhook/register\n```\n\nParameters:\n\n```\nclientId: your client reference\n```\n\nRequest body:\n\n```\ntype: string (required) - scpecifies which type of updates will be sent from Canopy, one of [\"PASSPORT_STATUS_UPDATES\", \"REQUEST_STATUS_UPDATES\"];\ncallbackUrl: string (required) - the URL of the webhook endpoint;\nadditionalSettings: string[] (optional) - list of Rent Passport sections for which updates will be sent;\n  - This field should only be added in case \"PASSPORT_STATUS_UPDATES\" webhook type is specified.\n  - The following sections can be specified inside the array: [\"INCOME\", \"RENT\", \"CREDIT_CHECK\", \"SAVINGS\", \"RENTAL_PREFERENCES\", \"EMPLOYEE_REFERENCE\", \"LANDLORD_REFERENCE\"]\n  - There is no need to explicitly specify the names of all sections if you want to receive all updates. Just send an empty array - [].\n```\n\nSuccessful response body:\n\n```\n\"success\": true,\n\"webhookType\": string,\n\"callbackUrl\": string\n```\n\nIf you subscribed to the `REQUEST_STATUS_UPDATES` type, the updates will be sent to the `callbackUrl` each time one of the following events trigger:\n\n- `INVITED` - the user was invited to connect;\n\n- `INVITE_RESENT` - resent invitation email for the user;\n\n- `CONNECTED` - user accepts the connection;\n\n- `CONNECTION_REJECTED` - user rejects the connection;\n\n- `CONNECTION_STOPPED` - user stops the connection;\n\n- `SENDING_COMPLETED_PASSPORT_FAILED` - sending the completed passport to client failed;\n\n- `PASSPORT_COMPLETED` - user complete his passport and the document was sent;\n\n- `INVALID_APPLICATION_DETAILS` - client's request body with application details was invalid;\n\nOnce `REQUEST_STATUS_UPDATES` event trigger, the Canopy should sent the notification to `callbackUrl` in the following format:\n\n```\ncanopyReferenceId: uuid,\nclientReferenceId: string,\nnotes: string,\n```\n\nIf you are subscribed to the `PASSPORT_STATUS_UPDATES` type, the updates will be sent to the `callbackUrl` when one of the following Rent Passport sections is updated (if updates for this section requested):\n\n- `CREDIT CHECK`\n\n- `INCOME`\n\n- `RENT`\n\n- `SAVINGS`\n\n- `LANDLORD REFERENCE` - optional, only if FULL SCREENING requested;\n\n- `EMPLOYER REFERENCE` - optional, only if FULL SCREENING requested;\n\nOnce `PASSPORT_STATUS_UPDATES` event trigger, the Canopy should sent the notification to `callbackUrl` in the following format:\n\n```\ncanopyReferenceId: uuid,\nclientReferenceId: uuid,\nupdatedSection: {\n  type: enum - one of [INCOME, RENT, CREDIT_CHECK, SAVINGS, EMPLOYEE_REFERENCE, LANDLORD_REFERENCE],\n  newStatus: enum - one of [NOT_STARTED, IN_PROGRESS, DONE],\n  updatedAt: ISODateTime,\n},\ninstant: {\n  status: enum - one of [NOT_STARTED, IN_PROGRESS, ACCEPT, CONSIDER, HIGH_RISK],\n  sections: {\n    income: enum - one of [NOT_STARTED, IN_PROGRESS, DONE],\n    rent: enum - one of [NOT_STARTED, IN_PROGRESS, DONE],\n    creditCheck: enum - one of [NOT_STARTED, IN_PROGRESS, DONE],\n    savings: enum - one of [NOT_STARTED, IN_PROGRESS, DONE],\n  };\n};\nfull: { /* optional field, sent only if FULL SCREENING requested  */\n  status: enum - one of [NOT_STARTED, IN_PROGRESS, ACCEPT, CONSIDER, HIGH_RISK],\n  sections: {\n    employerReference: enum - one of [NOT_STARTED, IN_PROGRESS, DONE],\n    landlordReference: enum - one of [NOT_STARTED, IN_PROGRESS, DONE],\n  };\n};\nglobalStatus: enum - one of [NOT_STARTED, IN_PROGRESS, ACCEPT, CONSIDER, HIGH_RISK],\n```\n\n### Unregister Webhook\n\nThe endpoint below unregisters webhook and stops sending Rent Passport updates to the specified callback URL.\n\n```\nDELETE /referencing-requests/client/:clientId/webhook/:webhookType\n```\n\nParameters:\n\n```\nclientId: your client reference,\nwebhookType: the type of the webhook you want to unregister\n```\n\nSuccessful response body:\n\n```\n\"success\": true,\n\"webhookType\": string\n```\n\nUnsuccessful response body:\n\n```\n/* If you don't have webhook subscriptions of the specified type */\n\n\"success\": false,\n\"requestId\" — the identifier of the request,\n\"error\": {\n  \"status\": 404,\n  \"type\" — error type,\n  \"message\" — “No webhooks of the specified type found”,\n}\n```\n\n## Errors\n\nWe use conventional HTTP response codes to indicate the success or failure of an API request, typically one of:\n\n- 2xx - indicate success\n- 4xx - indicate a client error with information provided (missign required parameters etc..)\n- 5xx - indicate an error with the Canopy platform\n\nWe suggest you wrap 4xx errors in your client and provide a user friendly message to your end users as part of the integration.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstemount%2Fcanopy-apidocs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstemount%2Fcanopy-apidocs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstemount%2Fcanopy-apidocs/lists"}