PHASE 01 · Start
From API key issuance to dev setup
STEP 01
Add app & get API keys
To call the Open API, create an app and get a Client ID and Client Secret.
Create an app
- App screen Fill out the application form.
- Enter service name, English name (channel code), and service URL, then submit.
- After ops review, a private channel is created and you'll get the result by email. Once approved, create API keys on the app detail page.
Issue API client
- App details On the API client section, [Add client] click
- Enter Client ID (free, up to 100 chars) and select scopes.
- Shown immediately after creation Save the Client Secret immediately in a safe place This value won't be shown again.
Scopes
buildingUnit:readBUILDING_UNIT_READView roomsbuildingUnit:writeBUILDING_UNIT_WRITECreate/Edit room mappingbooking:readBOOKING_READView bookingsbooking:writeBOOKING_WRITECreate/Edit bookingscontract:readCONTRACT_READView contractscontract:writeCONTRACT_WRITECreate/Edit contracts (Method B)user:writeUSER_WRITECreate users (Method A · login integration)userLoginTicket:writeUSER_LOGIN_TICKET_WRITEIssue login ticket (Method A · login integration)chat:readCHAT_READView chatschat:writeCHAT_WRITECreate/Send chats
Result
With the Client ID and Client Secret,Authorization: Basic … they are used in the request header for all API requests.STEP 02
Register test room & set channel mapping
To register contracts/reservations via API, create a test room and set channel mapping.
Procedure
- Host screen Register a new room.
- Channel mapping screen Select the registered room and set room-level and unit-level mappings. Room-level mapping is optional, but unit-level mapping is required to register contracts via the Open API. Set the external property ID to the room ID used by that channel.
- To view the registered room on the guest page, /rooms/{roomId}visit the guest page.
Note
External property ID example https://www.airbnb.co.kr/rooms/1252576808547167623 1252576808547167623STEP 03
Explore docs with MCP
Register plott LIFE Open API's MCP server with AI coding agents (Claude Code, Cursor, etc.) so agents can read the API spec immediately and speed up integration.
Register with Claude Code
claude mcp add --transport http plott-life-partner \ https://life.plott.co.kr/api/open/mcp \ --header "Authorization: Basic {base64(clientId:clientSecret)}"
{base64(clientId:clientSecret)} is the Client ID and Secret issued in Step 01 clientId:clientSecret concatenated with a colon and base64-encoded.


PHASE 02 · Integration
Select an integration method and implement/operate it
IMPLEMENT & OPERATE
Choose integration method
Two integration methods depending on how much your service handles Method A · Login integration One is the handoff method: integrate only listings and login, handing off contracts/payments to plott LIFE, Method B · Contract integration the other integrates contract APIs so sales finish inside the partner app. Select a tab below to view its implementation and operation steps.
Select a method based on how much your service handles. Below shows implementation and operation steps for the selected method. Common steps (app request & key, test room/channel mapping, MCP) and the public channel steps are identical for both.
Method A · Login integration (Handoff)
Show only listings in your app and hand off contracts/payments to plott LIFE. Pre-create users and issue a login ticket (SSO) so users land on plott LIFE already logged in. Required scopes areuser:write, userLoginTicket:write are.IMPLEMENT · Login integration
Implementation
1. Room list integration
This is where your service queries plott LIFE listings and shows them to users.
GET /open/v1/building-unit-type Fetch the room list via the API, GET /open/v1/building-unit-type/{id} and fetch single-room details via the API. The list uses page·size pagination, default size is 20. Infinite scroll uses the response's totalItems field to determine whether more items exist.
pageOptionalPage number starting at 0sizeOptional · default 20Items per pageoperationStatusRecommendedWhen showing to users, query only PUBLISHED (Operating).
const res = await fetch( 'https://life.plott.co.kr/api/open/v1/building-unit-type?page=0&size=20&operationStatus=PUBLISHED', { headers: { Authorization: `Basic ${credentials}` } }, ); const { items, totalItems, totalPages } = await res.json();
Note
Pricing rules (pro-rated rent, discounts, maintenance fee, deposit, service fee) and storage method (direct call / mirroring) are the same for both methods. See detailed formulas and examples in API docs See in API docs.2. User creation integration
POST /open/v1/user Create your users as plott LIFE members. externalUserId Idempotent using the partner's user identifier; returns the existing member ID if already created.
externalUserIdRequiredPartner user identifier (idempotency key)emailRequiredUser emailfirstName / lastNameRequiredFirst name / Last namephoneCode / phoneNumberRequiredCountry code / phone number (e.g., 82 / 1012345678)countryCodeOptionalCountry code (e.g., KR)
const res = await fetch('https://life.plott.co.kr/api/open/v1/user', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Basic ${credentials}`, }, body: JSON.stringify({ externalUserId: 'partner-user-001', email: 'user@example.com', firstName: '길동', lastName: '홍', phoneCode: '82', phoneNumber: '1012345678', countryCode: 'KR', }), }); const { id } = await res.json(); // 플라트라이프 회원 ID
3. Login ticket issuance
POST /open/v1/userLoginTicket Issue a one-time login ticket for the member. The request should include userId (the member creation response's id) or externalUserId include one of them. The returned ticket is Valid for 5 minutes and single-use so issue it right before redirecting the user to plott LIFE.
userIdChoose one: userId or externalUserIdplott LIFE member ID (id from user creation response)externalUserIdChoose one: userId or externalUserIdPartner service's user identifier
const res = await fetch( 'https://life.plott.co.kr/api/open/v1/userLoginTicket', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Basic ${credentials}`, }, body: JSON.stringify({ externalUserId: 'partner-user-001' }), }, ); const { ticket } = await res.json(); // 5분 TTL · 1회용
Tip
This method doesn't integrate contract APIs. Contracts and payments happen on plott LIFE, so implement only listing display and login integration.OPERATE · Login integration
Operation
- Show listings in your service.
- When a user selects a listing, issue that member's login ticket (If no member, create one and then issue.)
- Include the issued ticket with
https://life.plott.co.kr/rooms/{id}?ticket=<ticket>and redirect to plott LIFE. plott LIFE will exchange the ticket and auto-login log them in. - Contracts and payments proceed on plott LIFE. Your service doesn't handle the contract flow.
Ticket lifespan
Login tickets are valid for 5 minutes and single-use. Issue right before redirect and deliver without delay.PHASE 03 · Public Channel
After verification, switch to the public channel to begin full operation
PUBLIC CHANNEL
Request public channel review
If integration is verified in a private channel, request public channel access to reach all hosts' listings. This step is the same for both methods.
How to request
- App details On the app's status card [Request public channel access] Click it.
- Our operations team will review and email the result.
- If rejected, check the reason, fix the issue, and reapply.
PUBLIC CHANNEL
Public channel activation
When public, you can query all plott LIFE hosts' listings via Open API. Pick listings to handle, set channel mapping, and operate using your chosen integration flow.
View all listings
const res = await fetch( 'https://life.plott.co.kr/api/open/v1/building-unit-type?page=0&size=20', { headers: { Authorization: `Basic ${credentials}` } }, ); const { items, totalItems, totalPages } = await res.json();
Default behavior
By default,Operating Only rooms with 'Operating' status are shown. To view only your listings, isMine=true you can request it.REFERENCE · Common items
Notes on authentication, errors, and Rate Limit
COMMON
Authentication
All Open API requests use HTTP Basic auth. App details obtained from Client ID and Client Secret join with a colon and encode in base64 Authorization include it in the header.
const credentials = Buffer.from( `${process.env.CLIENT_ID}:${process.env.CLIENT_SECRET}`, ).toString('base64'); const res = await fetch('https://life.plott.co.kr/api/open/v1/contract-channel', { headers: { Authorization: `Basic ${credentials}`, }, });
Client Secret security
Client Secret is shown only once when issued. If it's lost or exposed, App details delete the client immediately and issue a new one.COMMON
Error responses
When an error occurs, RFC 9457 Problem Detail it responds in the following format.
{
"type": "about:blank",
"title": "Not Found",
"status": 404,
"detail": "예약 매핑을 찾을 수 없습니다.",
"instance": "/open/v1/booking"
}typeError type URItitleHTTP status textstatusHTTP status codedetailError detailinstanceRequest path
COMMON
Rate Limit
To ensure stability and fair use, the Open API enforces rate limits.
ScopeAll endpoints under /open/**Limit unitHost accountLimit300 requests per minuteRefill methodGreedy refill: ~5 tokens refilled every second.
Rate-limit exceeded response
Requests exceeding the limit are rejected immediately, 429 Too Many Requests and an error response is returned.
Recommended client handling
429When you receive the response, do not retry immediately, wait a while before retrying.- On average about 200ms intervals is stable.
- For batch jobs needing many requests quickly, space calls or use exponential backoff.
Tip
Under normal usage,429 if it happens often, contact us to discuss raising your limit.DOCUMENTATION
View full endpoint specs
See request/response schemas, parameters, and error codes in one place.