接口概述

简介

基于无码丰富的医疗基础数据和持续迭代的数据生产引擎,以灵活多样的开放接口将高度结构化的行业数据集、数据处理算法能力、深度知识图谱关系等赋能开放给合作伙伴,与合作伙伴共享数据能力,共同打造更具竞争力的应用生态。

无码数据开放服务主要覆盖医疗应用场景和数据应用能力,包括:医疗基础数据开放共享、查病问药智能算法服务开放、资讯文本处理服务、医疗数据众包能力开放以及基于医疗场景化能力的其他开放服务。接口分批次开放中,已开放接口仍有较大弹性,如有未满足的场景化需求,可单独对接。

主要开放能力概览

高度结构化的医疗基础数据

累计百万级别医疗领域高度结构化的基础数据,覆盖医疗机构、药品、疫苗、疾病、症状、活性成分、医生、临床试验等,为常见医疗服务场景提供底层基础数据支持。

智能算法辅助寻医问药

通过大量自然语言诊断数据学习,构建了持续迭代的自然语言智能算法推荐能力,可提供场景化的识别意图、智能分诊、辅助疾病判断、辅助用药推荐等智能服务。

可定制的资讯文本处理服务

无码在以就诊问问为代表的实践中,打造出了高效、稳定、智能的资讯理解及处理服务能力。目前已累计数千万资讯处理量,日吞吐量峰值达数十万篇。支持从资讯源获取、资讯内容抽取、多语言转换、自动评分、自动摘要、话题聚合、智能分类打标、动态时间线跟踪等全流程自动化,现已可通过开放服务获取基础或个性化的资讯处理能力。

共享开放的专业众包能力

拥有规模化的专业众包团队,具备算法+专业众包+自动质控融合的稳定数据处理流程,目前众包平台已吸纳数百位来自临床医师/药师、高校硕博(浙大、复旦)等医疗行业从业者或医药专业高校师生,来源专业覆盖全科,可持续输出高效、稳定、高质量的专业数据服务能力。

API 调用说明

以 appid +token+签名方式,进行应用对接,支持按 appid 限定调用范围。

调用方式基本介绍

基于 HTTP 协议调用 API,基本调用流程为:根据 API 填充参数 > 生成签名 > 拼装 HTTP 请求 > 发起 HTTP 请求> 获取 HTTP 响应 > 解析 json 结果。

调用主路径

https://medical.nocode.com/open/

公共参数(签名约定)

调用任何一个 API 都必须在 HTTP Header 中传入的参数。

参数类型是否必填描述
appidstring私有的 appid
signstring输入参数的签名结果
timestampstringunix 时间戳,单位毫秒(与服务提供方的服务器时差不超过 1 分钟)

签名算法

在 HTTP 请求中的 Header 中需发送 sign 字段,sign 字段为将 appid、token 和 timestamp 加密后的签名内容。签名算法为 lowercase(md5(appid+token+timestamp))

示例:

appid: ENHmKoxq97i4eRHn
token: LUZa2HfaxoLkAbgVc3BfNMzG6EaGJHvr
timestamp: 1561952337000
sign: 323fa1f3c22ea7e0fb4886513205dd87 =
lowercase(md5(ENHmKoxq97i4eRHnLUZa2HfaxoLkAbgVc3BfNMzG6EaGJHvr1561952337000))

协议约定

返回内容为 JSON 格式。HTTP header 可加上 Content-Type:application/json 为了方便排查问题,建议调用的时候 header 加上 X-Request-ID 值为 uuid

如: X-Request-ID:c5159cf9-1b60-41a8-90fb-5e507c8e01b9

安全策略

  1. 为防止请求被拦截并伪造攻击,请勿将该接口直接用于前端开发。
  2. 使用 HTTPS 协议,减少信息被拦截和伪造的风险。

错误码

当请求错误时,程序将返回 HTTP status 400,body 内容为 json 格式

{
    "error":{
        "code": CODE_VALUE_INT,
        "message": "MESSAGE_VALUE_STRING"
    }
}

其中 code 可选值以下几种情况:

400101: sign 签名校验错误
400102: timestamp 过期
400103: 缺少时间戳
400104: app_id 不正确
400105: 非法的时间戳
400108: 参数不合法
400109: 系统错误
400110: 没有接口权限
400111: 找不到该条数据
400112: 已经超过当天最大调用量
400113: 您的请求过于频繁,请稍后再试
400114: 调用来源不合法
400115: 余额不足
400116: 不在授权有效期内

请求示例

以药品包装详情查询示例接口 ms.drug.detail.get 为例,路由是 v2/nc.ms.drug.package.detail

接口地址(仅作示例)https://medical.nocode.com/open/v2/nc.ms.drug.package.detail

入参示例(CURL):

curl -X GET \
  'https://medical.nocode.com/open/v2/nc.ms.drug.package.detail?drug_package_id=f874aca5b4d86f96' \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'appid: JbdDAvbUDtEiRn8c' \
  -H 'sign: fa755915f4e211e02de2bd8227d13deb' \
  -H 'timestamp: 1575976883000'

返回结果示例

{
  "data": {
    "drug_package_id": "8c87c78599348648",
    "drug_approval_number_id": "7LeafcSS6jv",
    "generic_name": "复方头孢克洛片",
    "drug_generic_id": "7EZnbDsO26X",
    "trade_name": "毕利",
    "dosage_form": "片剂",
    "approval_number": "国药准字H20050768",
    "nhsa_drug_code": null,
    "images": [],
    "state": 1,
    "redirect_id": null,
    "is_rx": true,
    "otc_type": null,
    "brand_name": "毕利",
    "package": "10片"
  }
}

Java 代码调用示例

import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @author nocode tech
 */
public class NocodeOpenApiRequestDemo {

    public static void main(String[] args) {
        getRequestDemo();
        postRequestDemo();
    }

    /**
     * GET 请求示例
     */
    private static void getRequestDemo() {
        String url = "https://medical.nocode.com/open/v2/nc.ms.drug.generic.detail.get?drug_generic_id=7vBZEIcLZxj";
        String appId = "REPLACE_YOUR_APP_ID";
        String token = "REPLACE_YOUR_TOKEN";
        String timestamp = String.valueOf(System.currentTimeMillis());

        HttpHeaders headers = new HttpHeaders();
        headers.add("appid", appId);
        headers.add("sign", DigestUtils.md5DigestAsHex((appId + token + timestamp).getBytes()));
        headers.add("timestamp", timestamp);
        HttpEntity<?> requestEntity = new HttpEntity<>(headers);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<JsonNode> exchange = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        System.out.println("Response : " + exchange);
    }

    /**
     * POST 请求示例
     */
    private static void postRequestDemo() {
        String url = "https://medical.nocode.com/open/v2/nc.ms.smart.department.recommend"
        //设置查询参数
        Map<String, String> body = new HashMap<>();
        body.put("content", "身体头疼");

        String appId = "REPLACE_YOUR_APP_ID";
        String token = "REPLACE_YOUR_TOKEN";
        String timestamp = String.valueOf(System.currentTimeMillis());

        HttpHeaders headers = new HttpHeaders();
        headers.add("appid", appId);
        headers.add("sign", DigestUtils.md5DigestAsHex((appId + token + timestamp).getBytes()));
        headers.add("timestamp", timestamp);
        headers.set("Content-Type", "application/json");
        HttpEntity<?> requestEntity = new HttpEntity<>(body, headers);

        RestTemplate restTemplate = new RestTemplate();
        JsonNode jsonNode = restTemplate.postForObject(url, requestEntity, JsonNode.class);
        System.out.println("Response : " + jsonNode);
    }
}

Python 代码调用示例

"""
API 接口调用示例

本示例演示如何使用 Python 的 httpx 库调用 API 接口,
包括 GET 请求和 POST 请求的实现方式。
"""

import httpx
import time
import hashlib
import json
from typing import Dict


def generate_headers(app_id: str, token: str) -> Dict[str, str]:
    """
    生成API请求所需的通用头信息
    
    Args:
        app_id: 应用 ID
        token: 应用令牌
        
    Returns:
        包含 appid、sign 和 timestamp 的请求头字典
    """
    timestamp = str(int(time.time() * 1000))
    sign = hashlib.md5(f"{app_id}{token}{timestamp}".encode()).hexdigest()
    
    return {
        "appid": app_id,
        "sign": sign,
        "timestamp": timestamp
    }


def get_request_demo() -> None:
    """
    药品通用名详情查询示例 ( GET 请求)
    """
    # API配置
    url = "https://medical.nocode.com/open/v2/nc.ms.drug.generic.detail.get?drug_generic_id=7vBZEIcLZxj"
    app_id = "REPLACE_YOUR_APP_ID"
    token = "REPLACE_YOUR_TOKEN"
    
    # 生成请求头
    headers = generate_headers(app_id, token)
    
    try:
        print("发送 GET 请求...")
        with httpx.Client() as client:
            response = client.get(url, headers=headers)
            response.raise_for_status()  # 检查请求是否成功
        
        # 格式化输出响应结果
        print(" GET 请求响应结果:")
        print(json.dumps(response.json(), ensure_ascii=False, indent=2))
    except httpx.HTTPStatusError as e:
        print(f" GET 请求 HTTP 错误: {e.response.status_code} - {e.response.text}")
    except Exception as e:
        print(f" GET 请求错误: {str(e)}")


def post_request_demo() -> None:
    """
    智能科室推荐示例 ( POST 请求)
    """
    # API配置
    url = "https://medical.nocode.com/open/v2/nc.ms.smart.department.recommend"
    app_id = "REPLACE_YOUR_APP_ID"
    token = "REPLACE_YOUR_TOKEN"
    
    # 生成请求头并添加Content-Type
    headers = generate_headers(app_id, token)
    headers["Content-Type"] = "application/json"
    
    # 请求体
    body = {
        "content": "头痛挂什么科"
    }
    
    try:
        print("发送 POST 请求...")
        with httpx.Client() as client:
            response = client.post(url, headers=headers, json=body)
            response.raise_for_status()  # 检查请求是否成功
        
        # 格式化输出响应结果
        print(" POST 请求响应结果:")
        print(json.dumps(response.json(), ensure_ascii=False, indent=2))
    except httpx.HTTPStatusError as e:
        print(f" POST 请求 HTTP 错误: {e.response.status_code} - {e.response.text}")
    except Exception as e:
        print(f" POST 请求错误: {str(e)}")


def main() -> None:
    get_request_demo()
    
    post_request_demo()


if __name__ == "__main__":
    main()

Node 代码调用示例


/**
 * API 请求示例代码
 * 演示如何使用 axios 发送 GET 和 POST 请求 API
 */
const axios = require('axios');
const crypto = require('crypto');

/**
 * 生成 API 请求所需的通用头信息
 * @param {string} appId - 应用 ID
 * @param {string} token - 应用令牌
 * @returns {Object} 包含 appid、sign 和 timestamp 的请求头对象
 */
function generateHeaders(appId, token) {
  const timestamp = Date.now().toString();
  const sign = crypto.createHash('md5')
    .update(`${appId}${token}${timestamp}`)
    .digest('hex');
  
  return {
    "appid": appId,
    "sign": sign,
    "timestamp": timestamp
  };
}

/**
 * 药品通用名详情查询示例 ( GET 请求)
 * @returns {Promise<void>}
 */
async function getRequestDemo() {
  // API配置
  const url = "https://medical.nocode.com/open/v2/nc.ms.drug.generic.detail.get?drug_generic_id=7vBZEIcLZxj";
  const appId = "REPLACE_YOUR_APP_ID";
  const token = "REPLACE_YOUR_TOKEN";
  
  // 生成请求头
  const headers = generateHeaders(appId, token);

  try {
    console.log("发送 GET 请求...");
    const response = await axios.get(url, { headers });
    console.log(" GET 请求响应结果:");
    console.log(JSON.stringify(response.data, null, 2));
  } catch (error) {
    console.error(" GET 请求错误:", error.response?.data || error.message);
  }
}

/**
 * 智能科室推荐示例 (POST请求)
 * @returns {Promise<void>}
 */
async function postRequestDemo() {
  // API配置
  const url = "https://medical.nocode.com/open/v2/nc.ms.smart.department.recommend";
  const appId = "REPLACE_YOUR_APP_ID";
  const token = "REPLACE_YOUR_TOKEN";
  

  // 生成请求头并添加 Content-Type 
  const headers = {
    ...generateHeaders(appId, token),
    "Content-Type": "application/json"
  };

  // 请求体
  const body = {
    "content": "头痛挂什么科"
  };

  try {
    console.log("发送 POST 请求...");
    const response = await axios.post(url, body, { headers });
    console.log(" POST 请求响应结果:");
    console.log(JSON.stringify(response.data, null, 2));
  } catch (error) {
    console.error(" POST 请求错误:", error.response?.data || error.message);
  }
}

/**
 * 主函数 - 依次执行 GET 和 POST 请求示例
 */
async function main() {
  await getRequestDemo();
  
  await postRequestDemo();
}

// 执行示例
main().catch(error => {
  console.error("程序执行错误:", error);
}); 

;