Lingara Lingara 문서 학습 가이드 API 라이브러리 앱 만들기 웹 앱
언어: 한국어

인증

API 버전 2026-10-affable-towhee

Lingara API에 대한 모든 호출에는 액세스 토큰이 포함됩니다. 서버는 토큰 엔드포인트에서 OAuth 클라이언트의 ID와 시크릿을 교환해 액세스 토큰을 받습니다. 이는 서버가 자기 자신으로서 동작할 때 쓰는 OAuth 2.0의 클라이언트 자격 증명 그랜트입니다. 클라이언트는 Lingara 웹 앱의 연동 페이지(app.getlingara.com/admin)에서 만드세요.

세션 또는 클라이언트

Lingara 앱은 세션으로 로그인하며, 세션은 모든 스코프를 가지고 요금제의 사용 한도를 소모합니다. 클라이언트는 범위가 더 좁습니다. 클라이언트를 만들 때 허용할 스코프를 선택하며, 클라이언트가 받는 각 액세스 토큰에는 요청한 스코프만 담깁니다.

세 가지 값

클라이언트 ID는 lgr_cid_로 시작하며, 토큰 엔드포인트에서 클라이언트를 식별합니다. 비밀 값이 아닙니다.

클라이언트 시크릿은 lgr_cs_로 시작하며, 토큰 엔드포인트로만 보냅니다. 만들 때 한 번만 표시되므로 그때 복사해 두세요. Lingara는 그 해시만 저장합니다.

액세스 토큰은 lgr_at_로 시작하며 1시간 동안 유효합니다. /v1/ 아래 호출의 Authorization: Bearer 헤더에 넣고, 다른 곳에는 넣지 마세요. 그 헤더에 들어갈 수 있는 값은 액세스 토큰뿐입니다. 클라이언트 시크릿을 그 헤더로 보내면 401로 거부됩니다.

액세스 토큰 받기

grant_type=client_credentials를 담은 폼을 토큰 엔드포인트로 POST하세요. 클라이언트 ID와 시크릿은 HTTP Basic 인증으로 보내거나 client_id와 client_secret 폼 필드로 보내되, 둘 다 사용하지는 마세요. scope는 클라이언트에 허용된 스코프를 공백으로 구분한 목록입니다. 생략하면 클라이언트에 허용된 모든 스코프를 받습니다. 아래 명령은 뒤에 나오는 GET /v1/usage 예제에 필요한 스코프인 usage:read 하나만 요청합니다.

curl -X POST "https://api.getlingara.com/oauth/token" \
  -u "$LINGARA_CLIENT_ID:$LINGARA_CLIENT_SECRET" \
  -d "grant_type=client_credentials" \
  --data-urlencode "scope=usage:read"

응답에는 access_token, token_type(Bearer), expires_in(3600, 초 단위), 그리고 토큰이 실제로 가진 스코프인 scope가 담깁니다. 교환에 실패하면 /v1/의 {code, error} 엔벨로프가 아니라 OAuth 오류 형식인 {error, error_description}으로 응답합니다. 잘못되었거나 취소된 시크릿, 또는 삭제된 클라이언트는 401과 invalid_client로 거부됩니다. 클라이언트가 요청할 수 없는 스코프가 있으면 교환 전체가 400과 invalid_scope로 거부되며, 조용히 범위가 좁혀지는 일은 없습니다.

다른 Lingara 사용자를 대신해 동작하기

다른 Lingara 사용자를 대신해 동작하는 앱은 인가 코드 그랜트를 사용합니다. 사용자의 브라우저를 response_type=code, client_id, 등록한 것과 정확히 일치하는 redirect_uri, scope, state, 그리고 S256 code_challenge와 함께 인가 URL로 보내세요. 사용자는 Lingara의 동의 페이지를 보고 code, state, iss와 함께 redirect_uri로 돌아옵니다. 코드를 사용하기 전에 state가 보낸 값과 같은지, iss가 https://api.getlingara.com인지 확인하세요.

PKCE는 필수입니다

모든 클라이언트는 PKCE를 사용하며, 방식은 S256만 허용됩니다. 무작위 code_verifier를 만들고, 그 SHA-256 해시를 base64url로 인코딩해 code_challenge로 code_challenge_method=S256과 함께 보낸 뒤, 검증 값은 교환을 위해 보관하세요. 방식이 없거나 plain인 요청은 invalid_request로 거부됩니다.

코드 교환하기

60초 안에 클라이언트로 인증하면서 grant_type=authorization_code, code, 같은 redirect_uri, code_verifier를 토큰 엔드포인트로 POST하세요. 공개 클라이언트는 client_id만 보냅니다. 응답에는 lgr_rt_로 시작하는 refresh_token이 추가됩니다. 코드는 lgr_ac_로 시작하며 한 번만 사용할 수 있습니다. 두 번째 사용은 invalid_grant로 거부되고, 첫 교환에서 발급된 토큰도 무효가 됩니다.

갱신하기

액세스 토큰이 만료되면 다시 클라이언트로 인증하면서 grant_type=refresh_token과 refresh_token을 토큰 엔드포인트로 POST하세요. 갱신할 때마다 새 리프레시 토큰이 반환되므로 가장 최신 것만 보관하세요. 갱신은 동시에 하지 말고 순서대로 하세요. 교체된 지 60초가 지나서 사용된 이전 리프레시 토큰은 도난당한 것으로 간주되어, 해당 설치의 토큰이 invalid_grant로 무효가 됩니다. 30일 동안 사용하지 않은 리프레시 토큰은 만료됩니다. 토큰 엔드포인트는 주소별로 요청 수를 제한하므로, 토큰이 만료되었을 때만 갱신하세요.

네이티브 앱은 공개 클라이언트입니다

데스크톱, 모바일, 명령줄 앱은 시크릿을 안전하게 보관할 수 없으므로 공개 클라이언트입니다. 시크릿이 없고, 토큰 엔드포인트에 client_id만 보내며, http://127.0.0.1/callback(포트는 임의) 같은 루프백 리디렉션이나 com.example.app:/callback 같은 비공개 용도 스킴을 등록합니다. 사용자는 매번 동의 페이지를 봅니다. 웹 페이지는 클라이언트가 될 수 없습니다. 토큰 엔드포인트도 /v1/도 교차 출처 사전 요청(preflight)에 응답하지 않기 때문입니다.

사용자가 앱을 제거하면

사용자는 언제든지 연결된 앱에서, 또는 앱을 설치했다면 제거하는 방법으로 앱을 삭제할 수 있으며, 그러면 앱의 다음 호출은 401로 실패합니다. 사용자가 앱에서 로그아웃하면 취소 엔드포인트에서 해당 리프레시 토큰을 취소하세요. 그러면 해당 설치의 토큰이 무효가 됩니다.

토큰이 만료되면

1시간이 지나면 /v1/은 401과 코드 unauthorized, 그리고 invalid_token으로 시작하는 오류로 응답합니다. 호출이 401을 받거나 expires_in이 끝나기 조금 전에 다시 교환하고, 호출을 한 번 재시도하세요. 교환 자체가 invalid_client 또는 invalid_scope로 실패하면 클라이언트나 그 시크릿이 삭제, 취소되었거나 범위가 좁혀진 것입니다. 재시도해도 성공할 수 없으므로 중단하고 연동 페이지에서 고치세요. 토큰은 호출 사이에 보관하세요. 토큰 엔드포인트는 클라이언트별, 주소별로 교환 횟수를 제한하므로, 호출할 때마다 교환하는 프로그램은 한 시간 안에 429와 rate_limited로 거부됩니다(Retry-After만큼 기다리세요). 이 그랜트에는 리프레시 토큰이 없으며, 시크릿을 다시 교환합니다.

액세스 토큰은 API 경로에서만 작동합니다

액세스 토큰은 /v1/ 아래의 경로에서만 작동합니다. 다른 Lingara 경로로 보내면 401로 거부되며, 본문은 일반 텍스트이거나 error 필드 안에서 api_token_not_accepted로 시작합니다. /v1/ 경로가 사용하는 {code, error} 엔벨로프로는 절대 반환되지 않습니다. 아래와 같이 액세스 토큰을 Authorization 헤더에 담아 보내세요.

curl "https://api.getlingara.com/v1/usage" \
  -H "Authorization: Bearer $LINGARA_TOKEN"

스코프

각 작업에는 정확히 하나의 스코프가 필요하며, 해당 작업 페이지에 그 이름이 나와 있습니다. 그 스코프가 없는 액세스 토큰은 403과 코드 insufficient_scope로 거부됩니다. 그 작업을 호출하려면, 클라이언트에 허용된 경우 교환할 때 그 스코프를 요청하세요. 아래 표에 각 스코프와 그 스코프가 허용하는 작업이 나와 있습니다.

스코프
vocab:generate 어휘 목록을 생성합니다. 어휘 목록 생성
lesson_plans:read 내 수업 계획을 읽고 진행 상황에 다시 연결합니다. 수업 계획 가져오기수업 계획에 다시 연결
lesson_plans:write 수업 계획을 만듭니다. 수업 계획 만들기
tutor:converse 튜터와 대화합니다. 유료 요금제가 필요합니다. 튜터에게 한 턴 보내기
usage:read 남은 사용 한도 또는 `metered` 클라이언트의 이번 달 사용량을 확인합니다. 남은 사용 한도 가져오기
events:read 내 계정에 관한 이벤트를 읽고, 이벤트를 받을 엔드포인트를 등록합니다. 이벤트 목록이벤트 스트리밍
events:write 게임이나 연동에서 Lingara로 이벤트를 보냅니다. 이벤트 보내기

호출 비용은 누가 내나요

클라이언트는 두 가지 방식 중 하나로 과금되며, 만들 때 선택합니다. allowance 클라이언트는 소유자의 사용 한도, 즉 앱과 같은 사용 한도를 소모하며, 클라이언트의 액세스 토큰도 마찬가지입니다. 남은 양은 GET /v1/usage에서 확인할 수 있습니다. metered 클라이언트는 사용 한도를 소모하지 않고, 연동 페이지에서 설정하는 사용량 기반 과금 구독을 통해 크레딧 단위로 과금됩니다. 클라이언트 또는 계정이 월 지출 한도에 도달하면 호출이 402와 spend_cap_reached로 거부되고, 사용량 기반 과금이 활성화되지 않은 동안에는 402와 metered_billing_inactive로 거부됩니다. 수업 계획 하나는 10크레딧, 튜터와의 한 턴은 1크레딧, 어휘 생성 한 번은 3크레딧이므로 GET /v1/usage가 보고하는 units는 이 가중치로 크레딧으로 환산됩니다. 앱이 인가 코드로 받은 토큰을 사용해 다른 사용자를 대신해 하는 호출은 클라이언트의 방식과 관계없이 항상 그 사용자의 사용 한도를 소모합니다.

시크릿과 토큰은 서버에 보관하세요

클라이언트 시크릿은 직접 관리하는 서버에 두어야 하며, 누구나 읽을 수 있는 웹 페이지, 브라우저 확장 프로그램, 앱 번들에는 절대 넣지 마세요. 네이티브 앱은 공개 클라이언트이며 시크릿을 갖지 않습니다. /v1/도 토큰 엔드포인트도 교차 출처 사전 요청(preflight)에 응답하지 않으므로, 어차피 다른 사이트의 브라우저는 이들을 호출할 수 없습니다.

클라이언트 관리

연동 페이지(app.getlingara.com/admin)에서 클라이언트를 만들고, 이름을 바꾸고, 삭제하고, 각 클라이언트가 할 수 있는 일과 고정된 버전을 바꾸고, 시크릿을 만들고 취소할 수 있습니다. 클라이언트를 삭제하면 그 클라이언트가 가진 모든 액세스 토큰이 즉시 작동을 멈추고, 모든 사용자가 그 클라이언트에 준 권한도 끝납니다. 시크릿을 취소하면 그 시크릿으로 교환한 모든 액세스 토큰이 즉시 작동을 멈춥니다. 클라이언트의 스코프를 좁히는 것도 즉시 적용되며, 넓히거나 버전을 바꾸는 것은 다음 교환부터 적용됩니다.

시크릿 교체하기

클라이언트는 한 번에 두 개의 시크릿을 가질 수 있습니다. 교체하려면 새 시크릿을 만들어 배포한 뒤, 연동 페이지에서 이전 시크릿의 마지막 사용 날짜가 더 이상 바뀌지 않으면 이전 시크릿을 취소하세요. 이미 새 시크릿을 가졌지만 아직 이전 시크릿으로 받은 토큰을 가진 프로세스는 401을 한 번 받고 다시 교환합니다. 클라이언트의 유일한 시크릿은 취소할 수 없습니다. 대체할 시크릿을 먼저 만들거나 클라이언트를 삭제하세요.

번역본과 영어 참조 문서의 내용이 다른 경우, 영어 참조 문서가 올바른 것으로 봅니다.