Naver Open API (Search, Papago, Clova)

N/A (REST API — no versioned Python package) · active · verified Sun Mar 01

Naver's consumer-facing Open API suite — provides programmatic access to South Korea's dominant search engine (70%+ market share), Papago translation, Clova OCR/AI services, Naver Maps, and Naver Login (OAuth). No official Python SDK exists — integration is done via direct HTTP requests using the requests library. Auth uses Client ID and Client Secret passed as HTTP headers. All APIs are registered and managed via the Naver Cloud Platform console. IMPORTANT: Naver Open API is Korea-first — registration UI, documentation, and error messages are primarily in Korean. Daily quota resets at 00:00 KST (UTC+9), not UTC.

Warnings

Install

Imports

Quickstart

Two different base URLs are used depending on the service: 'openapi.naver.com' for Search and Login APIs, 'naveropenapi.apigw.ntruss.com' for AI services (Papago, Clova). Using the wrong base URL returns a 404 with no helpful error message. Daily quota resets at midnight KST (UTC+9), not UTC.

import os
import requests

CLIENT_ID = os.environ['NAVER_CLIENT_ID']        # X-NCP-APIGW-API-KEY-ID
CLIENT_SECRET = os.environ['NAVER_CLIENT_SECRET']  # X-NCP-APIGW-API-KEY

headers = {
    'X-NCP-APIGW-API-KEY-ID': CLIENT_ID,
    'X-NCP-APIGW-API-KEY': CLIENT_SECRET,
}

# --- Search API (blog, news, web, image, shopping, book) ---
# Base URL: https://openapi.naver.com/v1/search/{type}.json
def search_blog(query: str, display: int = 10, start: int = 1):
    url = 'https://openapi.naver.com/v1/search/blog.json'
    params = {
        'query': query,
        'display': display,  # 1-100, default 10
        'start': start,      # 1-1000
        'sort': 'sim',       # 'sim' (relevance) or 'date'
    }
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()
    return response.json()

def search_news(query: str):
    url = 'https://openapi.naver.com/v1/search/news.json'
    params = {'query': query, 'display': 10, 'sort': 'date'}
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()
    return response.json()

# --- Papago Translation ---
# Supported language pairs: ko<->en, ko<->zh-CN, ko<->zh-TW, ko<->ja, ko<->es, ko<->fr, etc.
def translate(text: str, source: str = 'ko', target: str = 'en'):
    url = 'https://naveropenapi.apigw.ntruss.com/nmt/v1/translation'
    # NOTE: Papago uses different base URL than Search API
    data = {
        'source': source,
        'target': target,
        'text': text,
    }
    response = requests.post(url, headers=headers, data=data)
    response.raise_for_status()
    return response.json()['message']['result']['translatedText']

# --- Clova OCR ---
def ocr_image(image_url: str):
    url = 'https://naveropenapi.apigw.ntruss.com/ocr/v1/recognize'
    data = {
        'image': image_url,
        'lang': 'ko',
        'type': 'url',
    }
    response = requests.post(url, headers=headers, data=data)
    response.raise_for_status()
    return response.json()

# --- Naver Login (OAuth 2.0) ---
# Step 1: Redirect user to Naver auth URL
import urllib.parse

def get_naver_login_url(state: str) -> str:
    params = {
        'response_type': 'code',
        'client_id': CLIENT_ID,
        'redirect_uri': 'https://yourdomain.com/callback',
        'state': state,
    }
    return 'https://nid.naver.com/oauth2.0/authorize?' + urllib.parse.urlencode(params)

# Step 2: Exchange code for token
def get_naver_token(code: str, state: str) -> dict:
    url = 'https://nid.naver.com/oauth2.0/token'
    params = {
        'grant_type': 'authorization_code',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'code': code,
        'state': state,
    }
    response = requests.get(url, params=params)
    return response.json()

# Step 3: Get user profile
def get_naver_profile(access_token: str) -> dict:
    url = 'https://openapi.naver.com/v1/nid/me'
    headers_auth = {'Authorization': f'Bearer {access_token}'}
    response = requests.get(url, headers=headers_auth)
    return response.json()

view raw JSON →