NAV
java shell

牛客网API介绍

  1. 该文档基于牛客网API牛客网API通讯协议V2改写。接口调用协议没有发生变化。
  2. 线下测试环境域名为: https://dapi.nowcoder.com ,线上正式环境域名为: https://api.nowcoder.com
  3. 请注意所有请求都需要带上 /v1 前缀

接口协议及规范

接口支持https传输协议,URL接口遵循RESTful相关设计规范。如果使用HTTP协议调用,接口会尝试将请求重定向。

牛客网api验证与授权基于标准OAuth2.0。使用牛客网开放平台API接口之前,请先获取与账号相关联的apiKeytoken。 具体获取方式为登录牛客网企业版后,点击设置->账户设置->查看API KEY来查看apiKeytoken, 若未显示出token可以刷新页面重试。

名称 格式 描述
apiKey String 标识唯一调用者的Key,这里传参使用api_key
token String 基于OAuth2.0的token值,使用时加前缀 "Bearer "

请求头

名称 格式 描述
Authorization String 基于OAuth2.0的Token值

请求参数

api_key为接口调用时必须要带上的参数,其值为apiKey需登录牛客网企业版获取。在使用Postman执行HTTP请求时, GET请求的这个参数需要放在Query Params中,其他类型请求的这个参数需要放在Body中的x-www-form-unlencoded中, 值得注意的是,除了api_key之外,接口的特异化参数也需要按照这个规则传参。

名称 格式 描述
api_key String 标识唯一调用者的Key

某些接口需要传递多个参数,比如在批量创建考生时,就需要传多个考生的信息。对于这种情况,我们需要知道HTTP请求是可以传递键值重复的参数的, 在调用接口时,需要要顺序一次将多个参数填入,比如a=1&a=3&a=3。在需要传递多个对象形式的参数时,调用接口时可以这样处理: v1=1&v2=1&v1=2&v2=2,在牛客服务中,我们使用数组来处理重复参数,参数的在数组中的顺序与HTTP请求时传入的顺序相同。在批量创建考生的场景下, 对于多个考生的不同信息,比如:姓名和考号,我们会同时循环两个数组。分别从每个数组的固定位置取出姓名和考号,组成一个考生信息。最后如果信息无误,才会执行后面的操作。 而调用方在传递参数时,只需按考生顺序,传递所有考生的信息即可,比如:name=user1&key=key1&name=user2&key=key2, 具体示例可参考添加考生接口。

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.regex.Matcher;

public class IsPhone {
  /**
   * 是不是手机号
   */
  public static boolean isPhone(String s) {
    if (StringUtils.isBlank(s)) {
      return false;
    }
    boolean containLeft = s.contains("(");
    boolean containRight = s.contains(")");

    if (!(containLeft == containRight)) {
      return false;
    }

    String phone = s.trim().replace("+", "").replace("(", "").replace(")", "");
    if (phone.startsWith("86")) {
      phone = phone.substring(2);
    }
    if (phone.length() < 3) {
      return false;
    }
    if (!NumberUtils.isDigits(phone)) {
      return false;
    }
    if (isNativePhonePrefix(phone.substring(0, 3)) && !isOverSeaPhonePreFix(s)) {
      // +153076137580 这个是海外手机,但是去掉+,会被判断是国内手机开头,所以加上isOverSeaPhonePreFix判断
      return phone.length() == 11;
    } else {
      //如果是数字而又不是国内手机号,返回true
      return true;
    }
  }

  public static boolean isNativePhonePrefix(String prefix) {
    java.lang.String regexMobile = "^1([3-9][0-9])$";
    java.util.regex.Pattern p = java.util.regex.Pattern.compile(regexMobile);
    Matcher m = p.matcher(prefix.trim());
    return m.matches();
  }

  public static boolean isOverSeaPhonePreFix(String s) {
    if (!s.startsWith("+")) {
      return false;
    }

    if (s.startsWith("+86")) {
      return false;
    }

    return true;
  }
}
import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IsEmail {

  public static Pattern emailPattern =
      Pattern.compile("^([a-zA-Z0-9_\\+\\.-])+@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,8})");
  /**
   * 是不是邮箱
   */
  public static boolean isEmail(String email) {
    if (StringUtils.length(email) <= 40 && StringUtils.length(email) > 0) {
      Matcher matcher = emailPattern.matcher(email);
      return matcher.matches();
    } else {
      return false;
    }
  }
}

需要符合正则表达式:^([a-zA-Z0-9_+.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,8})且字符长度不超过40个。校验逻辑见java代码示例。

接口回应

如无特殊说明,接口采用json格式来描述返回信息且接口返回头中带有Content-Type: application/json, 比如:{"code":0,"msg":"OK","data": 接口返回信息}code=0在业务上表示成功;code!=0在业务上表示失败,msg中为具体错误信息。 data字段可能为空,它的数据结构可能是字符串、数字、json对象等。data具体的内容见接口文档。

如无特殊说明,接口中返回的时间均为unix时间戳(毫秒级)

接口没有返回200code!=0可以视为发生了异常。异常绝大部分是传参不合法,比如请求了不存在的资源、参数传递出现了问题。 接口有可能在传参异常时返回4xx4xx错误通常可以在返回的json中msg处获取出错原因。若出错原因无法直接解读,可以联系我们。 如果出现了5xx错误,请联系我们。 建议非200情况下打印出牛客网返回的完整response,其中40x错误建议将msg中信息在界面中展示给用户,方便用户处理。

这个报错信息代表接口授权失败,需要检查api_key参数和Authorization请求头是否传递正确。

如果认为接口出现了问题。在向牛客技术反馈问题需提供如下信息:账号id、接口地址、接口入参、调用时间、牛客返回的完整response

示例代码

示例代码提供了HTTP接口的调用样例。目前提供了shell和Java语言示例代码。点击右侧的shell标签或java标签即可查看。 示例代码,用于帮助开发者快速理解牛客api调用规范。代码仅供测试用。

shell示例代码

shell代码示例提供了接口的curl调用示例。开发者替换脚本中的api_key参数和Authorization校验头即可进行接口调用。 除此之外,代码示例中还包含了以json形式表示的接口的返回数据结构。

java示例代码

java代码示例提供了在Java程序中调用的示例。 为了消除重复代码,简化代码示例代码逻辑,示例代码中使用了NowcoderApiRequestUtils工具类对HTTP调用过程进行了封装。示例代码中仅保留了接口地址和请求参数信息。 NowcoderApiRequestUtils工具类和文档中的代码示例均托管在gitee。 下载代码至本地即可调试。

示例代码下载地址:https://gitee.com/nowcoder-guokaijun/nowcoder-api-http-call-demo/tree/master

下面是代码主要结构介绍

ConfigUtils

https://gitee.com/nowcoder-guokaijun/nowcoder-api-http-call-demo/blob/master/src/main/java/com/nowcoder/enterprise/javademo/utils/ConfigUtils.java

该类为牛客网企业版账户配置类,需要该类中的将TODO标注的配置改为开发者自己账户的配置。

全局配置类

public class ConfigUtils {

  private static final boolean USE_NOWCODER_API_ONLINE =
      false; // TODO 牛客接口环境,false的是线下测试环境、需要根据您的代码运行环境灵活配置
  private static final long NOWCODER_HR_ID_DEV = 0; // TODO 需要替换为您牛客线下测试环境的HrID
  private static final long NOWCODER_HR_ID_ONLINE = 0; // TODO 需要替换为您牛客线上正式环境的HrID
  private static final String API_KEY = "huaxinjiayou@126.com"; // TODO 需要替换为您的api_key
  private static final String TOKEN =
      "95da5da5da5da5da5da5da5da5da5ff81aa9c7a8512638f4c73a4e338f650a5c"; // TODO 需要替换为您的token

  private ConfigUtils() throws IllegalAccessException {
    throw new IllegalAccessException("Can not instantiate an util class.");
  }

  private static boolean useNowcoderAPIOnline() {
    return USE_NOWCODER_API_ONLINE;
  }

  public static long getNowcoderHrId() {
    if (useNowcoderAPIOnline()) {
      return NOWCODER_HR_ID_ONLINE;
    }
    return NOWCODER_HR_ID_DEV;
  }

  public static String getApiBaseUrl() {
    // 线上正式环境
    if (useNowcoderAPIOnline()) {
      return "https://api.nowcoder.com/v1";
    }
    // 线下测试环境
    return "https://dapi.nowcoder.com/v1";
  }

  public static String getApiKey() {
    return API_KEY;
  }

  public static String getAuthorization() {
    return "Bearer " + TOKEN;
  }
}

NowcoderApiRequestUtils

https://gitee.com/nowcoder-guokaijun/nowcoder-api-http-call-demo/blob/master/src/main/java/com/nowcoder/enterprise/javademo/utils/NowcoderApiRequestUtils.java

该类为封装了符合牛客API的传输协议的HTTP调用逻辑的静态工具类。在该类中,有两个出口方法request()getNowcoderHrId()。 其中request()方法的作用是将接口的特异化参数传入并执行HTTP调用,方法支持HTTP的GET、POST、PUT、DELETE方法的请求, 并根据不同的HTTP方法规范设置了api_key参数、Authorization校验头、Content-Type请求参数内容类型。 getNowcoderHrId()方法的作用是获取用户的HRId,以便在调用需要拼接接口url的方法时使用。

请求牛客API工具类

public class NowcoderApiRequestUtils {

  /**
   * HTTP调用牛客API并返回字符串,在调用之前根据请求方法设置了通用的请求头和请求参数,并将方法传入的参数置入HTTP请求中。
   *
   * @param path 请求路径,形如"/users/self"的字符串
   * @param params 请求参数,需传递除api_key参数之外的每个接口独有的参数。一个key能对应多个值,值不能为null。
   *               如果接口不需要其他参数,需要传递空Map,不能传null。
   * @param methodName http方法名称。取值范围为 GET、POST、PUT、DELETE 中的一个
   * @return 牛客接口json返回的字符串表示
   */
  public static String request(
      String path, MultiValuedMap<String, Object> params, String methodName) {
    if (HttpGet.METHOD_NAME.equals(methodName)) {
      return getRequest(path, params);
    }

    HttpEntityEnclosingRequestBase uriRequest;
    if (HttpPost.METHOD_NAME.equals(methodName)) {
      uriRequest = new HttpPost();
    } else if (HttpPut.METHOD_NAME.equals(methodName)) {
      uriRequest = new HttpPut();
    } else if (HttpDelete.METHOD_NAME.equals(methodName)) {
      uriRequest = new NowcoderHttpDelete();
    } else {
      throw new IllegalArgumentException("Bad methodName.");
    }
    uriRequest.setURI(URI.create(ConfigUtils.getApiBaseUrl() + path));

    List<NameValuePair> pairList = new ArrayList<>();
    pairList.add(new BasicNameValuePair("api_key", ConfigUtils.getApiKey()));
    params
        .entries()
        .forEach(
            (entry) -> {
              String key = entry.getKey();
              Object val = entry.getValue();
              if (key == null || val == null) return;
              pairList.add(new BasicNameValuePair(key, val.toString()));
            });
    uriRequest.setEntity(new UrlEncodedFormEntity(pairList, StandardCharsets.UTF_8));

    uriRequest.addHeader("Authorization", ConfigUtils.getAuthorization());
    return sendRequest(uriRequest);
  }

  // 执行GET请求
  private static String getRequest(String path, MultiValuedMap<String, Object> params) {

    List<String> pairs = new ArrayList<>();
    pairs.add("api_key=" + ConfigUtils.getApiKey());
    params
        .entries()
        .forEach(
            (entry) -> {
              String key = entry.getKey();
              Object val = entry.getValue();
              if (key == null || val == null) return;
              pairs.add(key + "=" + val);
            });
    String queryParams = StringUtils.join(pairs, "&");

    HttpGet get = new HttpGet(ConfigUtils.getApiBaseUrl() + path + "?" + queryParams);

    get.addHeader("Authorization", ConfigUtils.getAuthorization());

    return sendRequest(get);
  }

  // 发送请求并打印CURL
  private static String sendRequest(HttpRequestBase requestBase) {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    String responseString = null;
    try {
      CloseableHttpResponse response = httpClient.execute(requestBase);
      HttpEntity entity = response.getEntity();
      responseString = EntityUtils.toString(entity, StandardCharsets.UTF_8);
    } catch (IOException e) {
      e.printStackTrace();
    }
    String curlStr = toCurlStr(requestBase);
    System.out.println(curlStr);
    return responseString;
  }

  // 将一次HTTP请求转换成CURL
  private static String toCurlStr(HttpRequestBase requestBase) {
    String httpMethod = requestBase.getMethod();
    String uri = requestBase.getURI().toString();

    List<String> headers = new ArrayList<>();
    for (Header header : requestBase.getAllHeaders()) {
      headers.add(header.getName() + ": " + header.getValue());
    }
    String headersStr = "";
    if (CollectionUtils.isNotEmpty(headers)) {
      for (String header : headers) {
        headersStr += "\\\n --header '" + header + "' ";
      }
    }

    String dataRawStr = "";
    if (requestBase instanceof HttpEntityEnclosingRequestBase) {
      HttpEntity entity = ((HttpEntityEnclosingRequestBase) requestBase).getEntity();
      try {
        dataRawStr = EntityUtils.toString(entity, StandardCharsets.UTF_8);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    if (StringUtils.isNotEmpty(dataRawStr)) {
      dataRawStr = String.format("\\\n --data-raw '%s'", dataRawStr);
    }

    String template = "curl --location --request %s '%s' %s %s";
    return String.format(template, httpMethod, uri, headersStr, dataRawStr);
  }
}

NowcoderHTTPDelete

https://gitee.com/nowcoder-guokaijun/nowcoder-api-http-call-demo/blob/master/src/main/java/com/nowcoder/enterprise/javademo/utils/NowcoderHttpDelete.java

由于HTTPDelete类不支持传递参数内容,故实现了NowcoderHttpDelete类以便在使用DELETE请求时传递参数。该类仅在NowcoderApiRequestUtils中使用。

DELETE请求类

public class NowcoderHttpDelete extends HttpEntityEnclosingRequestBase {

  public static final String METHOD_NAME = HttpDelete.METHOD_NAME;

  public NowcoderHttpDelete() {
    super();
  }

  public NowcoderHttpDelete(final URI uri) {
    super();
    setURI(uri);
  }

  /** @throws IllegalArgumentException if the uri is invalid. */
  public NowcoderHttpDelete(final String uri) {
    super();
    setURI(URI.create(uri));
  }

  @Override
  public String getMethod() {
    return METHOD_NAME;
  }
}

src/test/java包下的测试类

使用NowcoderApiRequestUtils工具类对牛客API的接口进行了测试。

具体的测试代码

public class Test {
  @Test
  public void testGetUserTestInfo() {
    String path = "/users/self";
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}

接口文档组织形式

## 一句话描述接口

> 右侧为 java语言 和 shell语言的代码示例

阐明接口的业务背景、作用以及对接中常见问题。

### 接口地址`$method $uri`的形式表示接口地址,实际请求时,需要拼接`https://api.nowcoder.com/v1`的前缀。

### 请求参数

以表格形式展现的接口全部或部分主要的请求参数。

### 返回数据

以表格形式展现的接口全部或部分主要的返回数据。

接口文档模版

每一个接口除了描述接口的调用协议,还讲述了业务背景和对接中的常见问题。具体的组织形式见右侧示例代码。

接口目录简述

已“笔试-”开头的为笔试系统对接需要关注的接口。 已“面试-”开头的为面试系统对接需要关注的接口。 系统接口为获取用户信息所需接口。

牛客网回调服务介绍

牛客网回调服务提供了实现了一种事件发布订阅机制。开发者在订阅某些事件之后,牛客网回调服务将会在事件发生时,通过HTTP请求的形式通知开发者。

名词解释

回调配置

目前来说回调支持两种配置方式:

  1. 在调用创建实体接口(比如:笔试考生、面试房间)时订阅一个实体的回调。
  2. 由牛客开发者来配置回调。

回调接口协议

回调协议包含一次HTTP调用时牛客的请求形式和期望开发者系统的返回形式。

回调请求格式

对于GET请求,所有参数都放在HTTP的Query params中;对于POST请求,请求头为application/x-www-form-urlencoded,参数放在了Body中。

回调成功/失败判定

开发者系统的服务返回success这6个字符,视为回调成功。如果没有返回这六个字符,则视为回调失败。回调失败将会触发重试机制。

回调成功示例:纯HTTP响应格式如下:

  HTTP/1.1 200 OK
  Content-Type: text/plain
  Content-Length: 7

  success

回调重试机制

对于一次回调,牛客回调服务可能会尝试进行两次HTTP调用。 牛客回调服务会先尝试发送GET请求、如果请求失败,然后尝试发送POST请求。如果两次请求都失败了,牛客回调服务会认为这次请求失败了,并触发重试机制。

回调频率、次数

如果遇到回调失败,牛客回调服务会尝试重试4次,带上第一次失败的请求,总共尝试5次。

第几次调用 回调时机
第一次调用 回调触发
第二次调用 第一次失败10分钟后
第三次调用 第二次失败30分钟后
第四次调用 第三次失败60分钟后
第五次调用 第四次失败120分钟后

其他事项

回调类型

不同的回调类型有不同的回调配置方式,会携带不同的回调参数并在不同的回调时机回调开发者。

关于回调类型的具体信息见:笔试-回调服务面试-回调服务

回调服务地址

线下测试服务ip为:47.114.96.253,线上回调服务ip:47.99.92.255

牛客系统对接最佳实践

牛客网企业版作为成熟的技术人才招聘解决方案提供商,根据多年系统对接经验,总结了下面几种系统对接最佳实践。

名词解释

ATS:applicant tracking system,求职跟踪系统。在这里也可以指开发者需要与牛客对接的系统。
牛客/牛客网企业版:指牛客提供的接口服务以及回调服务

笔试系统对接最佳实践

对接模式一(推荐)

系统交互流程

  1. 企业的HR或者牛客项目同学,使用牛客网企业版管理后台在牛客系统创建试卷。
  2. ATS通过调用牛客API接口,可以查询在牛客中已经创建好的试卷。
  3. ATS中通过调用牛客API接口的方式,安排考生到牛客的试卷中。安排成功后,可以获取到考生的考试链接。在调用接口创建考生的同时,传递需要回调的地址。
  4. 在考生完成考试、作弊检测完成、人工判题完成等动作触发之后,牛客将考试成绩、成绩报告通过回调地址回传给ATS。 同时,ATS也可以选择在某一个时间点调用牛客API接口获取考生成绩。

代表企业:字节跳动、网易、moka、大易等绝大部分企业

对接模式二

系统交互流程

  1. 企业的HR或者牛客项目同学,使用牛客网企业版管理后台在牛客系统创建好试卷,并填好职位id(这个职位id用于关联企业ATS中的职位)。
  2. 试卷创建完成之后,可通过职位id定位一张试卷来创建考生。在调用接口创建考生的同时,传递需要回调的地址。
  3. 在考生完成考试、作弊检测完成、人工判题完成等动作触发之后,牛客将考试成绩、成绩报告通过回调地址回传给ATS。 同时,ATS也可以选择在某一个时间点调用牛客API接口获取考生成绩。

代表企业:阿里巴巴、中兴、OPPO等部分企业

对接模式三

系统交互流程:

  1. 企业的HR或者牛客项目同学,使用牛客网企业版管理后台在牛客系统创建试卷。
  2. 试卷创建完成之后,在ATS系统中关联岗位、试卷。在ATS中将候选人转移状态即可安排笔试、拿到考生考试链接。
  3. 在考生完成考试、作弊检测完成、人工判题完成等动作触发之后,牛客将考试成绩、成绩报告回传给ATS。 同时,ATS也可以选择在某一个时间点调用牛客API接口获取考生成绩。

代表企业:北森

面试系统对接最佳实践

对接模式一

系统交互流程

  1. 客户在牛客端创建账号,到对接方配置认证使用的api_key
  2. 在对接方推进面试流程,在牛客端进行面试
  3. 对接方、牛客端之间进行面试结果同步

笔试-试卷管理

一张试卷包含考试时长、考试起止时间、防作弊机制配置以及添加考生时需要录入信息等配置元信息。 在牛客系统中试卷可以认为是一场考试的抽象,在校园招聘业务场景下,一场考试应与一张试卷一一对应; 在社会招聘业务场景下,一张试卷可以认为是相似职位的通用考题。 一张试卷可以对应多个考生,所有的考生都属于一张试卷。考生在试卷之间没有关联关系,不同的试卷中可以创建唯一编号(添加考生接口的key字段)相同的考生。

试卷实体的关键字段

试卷实体的创建、删除和查询可调用试卷管理接口获取,下面是试卷实体的一些关键字段。

参数 类型 描述
id long 试卷id,唯一标识一张试卷。
paperName String 试卷名字。
duration int 试卷考试时长。
beginTime Date 试卷的开始时间。
endTime Date 试卷结束时间(对长期有效试卷,默认取值'2114-10-10T00:00')。
forever boolean 试卷是否长期有效,true是,false否。
createTime Date 试卷的创建时间。
beenTested boolean 试卷是否已经被使用。
started boolean 试卷是否已经开始。
finished boolean 试卷是否已结束。
summary String 试卷简介,考生在考试开始前会看到这些信息。
questionCount int 试卷试题的数量。
testCount int 试卷测评的数量。
needJudge int 试卷是否需要人工判题, 0表示需要,1表示不需要。
assignedCount int 已经分配的判卷数量。
setting Object 试卷相关配置信息, json格式。其中,试卷适用的职位id列表为该json下的"otherJobIds"字段,取值为int类型的职位id列表,职位id之间用","分隔,取值示例:""10000001,10000002"
score Float 试卷总分。
passScoreLine Float 及格线。
antiCheatStr String 防作弊机制。
signUpFieldTitles String 考生需要录入信息的所有字段,逗号拼接。
paperCodeLangInfo Object 试卷中编程题语言信息,对象结构见右侧说明
paperCodeLangInfo结构
{
  "codeQuestionCount": 2, // 编程题的数量,为0表示没有编程题
  "ojExerciseUrl": "https://xxx", // codeQuestionCount大于0时有值,表示:OJ在线编程常见输入输出练习地址
  "codeLangList": [ //codeQuestionCount大于0时有值,表示:对应题目数量和其支持的编程语言
    {
      "count": 2, // 题目数量
      "langList": ["C","C#","C++","Go","Groovy","Java","Javascript"] // 编程语言列表,为null表示不限语言
    }
  ]
}

获取试卷列表

public class Main {
@Test
  public void testGetPaperList() {
    String path = String.format("/papers/oid-%d", ConfigUtils.getNowcoderHrId());
    long projectId = 1643;

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("page", 1);
    mvMap.put("pageCount", 20);
    mvMap.put("orderBy", 0);
    mvMap.put("order", 2);
    mvMap.put("filter", 0);
    mvMap.put("query", "");
    mvMap.put("progressType", 0);
    mvMap.put("projectIdList", projectId);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/oid-30?api_key=huaxinjiayou@126.com&filter=0&pageCount=20&progressType=0&query=&orderBy=0&page=1&projectIdList=1643&order=2' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "totalCount" : 1,
    "totalPage" : 1,
    "currentPage" : 1,
    "datas" : [ {
      "id" : 17131890,
      "paperName" : "一张很久才开始的试卷",
      "createTime" : 1628137829000,
      "duration" : 120,
      "score" : 20,
      "personTotal" : 0,
      "avgTotal" : 0.0,
      "summary" : "1、考前请关闭其他浏览器窗口,关闭QQ、微信等即时通信软件,关闭屏保、Outlook等弹窗提示软件,考试中不要切换到考试窗口之外的区域。<br/>\n2、请在规定时间内完成题目,答题过程中系统自动即时,到时自动交卷,请掌握好答题进度;<br/>\n3、请诚信答题,考试全程不要跳出考试页面(在线编程题除外),后台将记录你的跳出次数。编程题交卷后,我们将进行代码相似度判断,标示作弊嫌疑代码。<br/>\n4、笔试过程中遇到任务问题,请通过在线咨询小窗发消息给我们,我们会有相应人员解答。<br/>",
      "logo" : null,
      "questionCount" : 1,
      "diffcult" : 0,
      "beginTime" : 1735660800000,
      "endTime" : 1738339200000,
      "previewUrl" : "https://examd.nowcoder.com/cts/preview/papers/17131890?p_token=L9mTCQXQaLsBUEfFzKlJMrKLgROj5Xk4",
      "testUrl" : "https://examd.nowcoder.com/cts/17131890/summary",
      "mobileTestUrl" : null,
      "assigned" : true,
      "testCount" : 0,
      "assignedCount" : 0,
      "paperSetting" : null,
      "presetUserCount" : 3,
      "paperExcelDownloadUrl" : null,
      "excelTaskStatus" : 0,
      "finished" : false,
      "started" : false,
      "setting" : {
        "logo" : "https://dev-private-public.oss-cn-hangzhou.aliyuncs.com/images/20201130/30_1606732062638/3669B06677BFB1053B71DAA1400C3083",
        "paperSummary" : "1. 请使用最新版Chrome浏览器作答(不低于82版),如考试需开启摄像头,请确保电脑带有摄像头。\n2. 一旦开始考试,请勿离开答题页面,除非当前目录明确提醒可以离开,前三次离开会有提醒,之后将不再提醒。各目录是否支持离开答题页面则取决于试卷具体设置,进入每个目录会有提示。\n3. 考试过程中允许使用草稿纸,请提前准备纸笔。允许上厕所等短暂离开,请控制离开时间。\n4. 考试期间如遇到断电、断网、死机等问题,关闭浏览器重新打开试卷链接即可继续做题。\n5. 遇到问题请即时反馈给考试主办方。",
        "examDisclaimer" : null,
        "antiJumpOut" : false,
        "antiDesignJumpOut" : true,
        "antiCodingJumpOut" : false,
        "codeSimilarRate" : 80,
        "setSourceCoderCheat" : false,
        "monitorPhone" : false,
        "allowMobileTest" : false,
        "noQueueUp" : true,
        "signUpFields" : [ {
          "title" : "姓名",
          "name" : "name",
          "format" : "",
          "need" : true,
          "edit" : 0,
          "valueType" : 0,
          "valueList" : null
        }, {
          "title" : "投递编号",
          "name" : "key",
          "format" : "",
          "need" : true,
          "edit" : 0,
          "valueType" : 0,
          "valueList" : null
        }, {
          "title" : "手机号码",
          "name" : "phone",
          "format" : "Phone",
          "need" : false,
          "edit" : 0,
          "valueType" : 0,
          "valueList" : null
        }, {
          "title" : "邮箱",
          "name" : "email",
          "format" : "Email",
          "need" : false,
          "edit" : 0,
          "valueType" : 0,
          "valueList" : null
        }, {
          "title" : "职位",
          "name" : "zhi2_wei4",
          "format" : "",
          "need" : false,
          "edit" : 0,
          "valueType" : 0,
          "valueList" : null
        }, {
          "title" : "学校",
          "name" : "xue2_xiao4",
          "format" : "",
          "need" : false,
          "edit" : 0,
          "valueType" : 0,
          "valueList" : null
        }, {
          "title" : "学历",
          "name" : "xue2_li4",
          "format" : "",
          "need" : false,
          "edit" : 0,
          "valueType" : 0,
          "valueList" : null
        } ],
        "relationType" : 0,
        "questionCategories" : {
          "5" : "问答"
        },
        "questionIdsTypes" : { },
        "questionScores" : null,
        "questionNewCounts" : null,
        "relationJsonString" : null,
        "questionCategoryRule" : null,
        "questionCategoryOrder" : "1,2,3,4,5",
        "randomQuestion" : false,
        "customCategory" : false,
        "randomFrequentType" : 0,
        "version" : "1.0",
        "questionTagNames" : { },
        "codingScoreRule" : 1,
        "chooseScoreRule" : 3,
        "checkCheat" : true,
        "allowCopy" : false,
        "allowCalculator" : false,
        "contestDomain" : null,
        "navLogoUrl" : null,
        "hideNowcoder" : false,
        "simulation" : false,
        "languageLimit" : false,
        "languageList" : [ ],
        "reportPlatform" : true,
        "forbidPreview" : true,
        "needMobileCamera" : false,
        "codePlayback" : false,
        "timeLimitType" : 0,
        "timeLimitDetail" : null,
        "tiankongScores" : "{}",
        "otherJobIds" : null,
        "subPaperSetting" : null,
        "uploadFileTimeRange" : 0,
        "videoAnswerQuestionRule" : null,
        "lateNoticeSetting" : null,
        "paper_end_summary" : "本场考试已结束,请保持您的手机、邮箱畅通,方便接收后续通知。",
        "allow_new" : false,
        "allow_camera" : false,
        "allow_screen_record" : false,
        "allow_message" : false,
        "question_disorder" : false,
        "option_disorder" : false,
        "not_need_judge_type" : "3_4",
        "need_judge_type" : "5",
        "faq" : [ ],
        "hide_return_button" : true
      },
      "beenTested" : false,
      "passScoreLine" : null,
      "projectId" : 1643,
      "projectName" : "liumeng测试",
      "departmentList" : null,
      "previewOverdueTime" : null,
      "paperType" : null,
      "hasNotAttendTestUser" : false,
      "antiCheatStr" : "开启举报平台",
      "signUpFieldTitles" : "投递编号,姓名,手机号码,邮箱,职位,学校,学历",
      "creatorHrId" : 30,
      "creatorHrName" : null,
      "needJudge" : 0,
      "notStartedCount" : 0,
      "inProgressCount" : 0,
      "expiredCount" : 0,
      "cheatTaskStatus" : 0,
      "faceDetectedRation" : 0.0,
      "codeDetectedRation" : 0.0,
      "screenDetectedRation" : 0.0,
      "hasCodeQuestion" : false,
      "hasCtsPic" : false,
      "hasScreen" : false,
      "questionDesc" : "问答 1 道",
      "interviewPaper" : null,
      "forever" : false
    } ],
    "ext" : null,
    "allTotalCount" : 1,
    "notStartedPaperCount" : 1,
    "testingPaperCount" : 0,
    "finishedPaperCount" : 0,
    "archivePaperCount" : 0
  }
}

获取一个账户下的试卷列表。支持分页。这个接口可以用于遍历牛客系统中已经创建好的试卷。

接口地址

GET /papers/oid-{ownerId}

请求参数

参数 类型 是否必传 默认值 描述
ownerId int HR系统的用户ID,需填充在url中
page int 1 第几页,从1开始。
pageCount int 20 每页20多少数据。无数量限制,可以传较大的值,但试卷数量多之后响应时长可能很长,不推荐这么做
orderBy int 0 试卷排序的依据项。0根据create_time排序,1根据做题人数排序,2根据平均分排序,3开考时间
order int 试卷的排列顺序。1代表升序,2代表降序
filter int 2 是否过滤。可不传,默认0。0不过滤, 1过滤掉不需要人工判卷的试卷
query String 试卷名称搜索,实现方式为SQLLIKE关键字的模糊搜索
paperType int 试卷类型:0.全部,1.普通笔试,2.ai面试。当paperType未传值或该参数不存在时,默认值为0,会返回笔试试卷+AI面试试卷(AI试卷名称自动添加#AI面试#前缀,以便于与笔试试卷区分);如果需要只返回笔试试卷,可以找客户经理进行配置
progressType int 试卷的状态:0.代表不限,1.表示未开始,2.表示进行中,3.表示结束
progressTypeList List<Integer> progressType的多值查询参数,多个参数之间用OR关系取并集;当启用该参数时,建议progressType参数默认取值0(progressType和progressTypeList两参数间,是And关系取交集的逻辑)
projectIdList List<Long> 限定试卷所属项目id,可传多个
otherJobIdList List<Long> 限定职位id,一般情况下不用传,可传多个,用于筛选出“试卷配置中指定了职位id“的试卷列表。关于职位id更多信息见系统对接模式2

返回数据

参数 描述
totalCount 数据(试卷)总数
totalPage 总共多少页
currentPage 当前是第几页,从第一页开始
datas 试卷信息数组,试卷关键信息见试卷关键返回字段

批量获取试卷

public class Main {
  @Test
  public void testGetPaperListByMultiPaperIds() {
    String path = "/papers/multi";

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("paperIds", 17071483);
    mvMap.put("paperIds", 17071578);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/multi?api_key=huaxinjiayou@126.com&paperIds=17071483&paperIds=17071578' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : [ {
    "id" : 17071483,
    "paperName" : "121",
    "createTime" : 1611214578000,
    "duration" : 120,
    "score" : 112,
    "personTotal" : 0,
    "avgTotal" : 0.0,
    "summary" : "1、考前请关闭其他浏览器窗口,关闭QQ、微信等即时通信软件,关闭屏保、Outlook等弹窗提示软件,考试中不要切换到考试窗口之外的区域。<br/>\n2、请在规定时间内完成题目,答题过程中系统自动即时,到时自动交卷,请掌握好答题进度;<br/>\n3、请诚信答题,考试全程不要跳出考试页面(在线编程题除外),后台将记录你的跳出次数。编程题交卷后,我们将进行代码相似度判断,标示作弊嫌疑代码。<br/>\n4、笔试过程中遇到任务问题,请通过在线咨询小窗发消息给我们,我们会有相应人员解答。<br/>",
    "logo" : null,
    "questionCount" : 4,
    "diffcult" : 0,
    "beginTime" : 1611214578000,
    "endTime" : 4568544000000,
    "previewUrl" : "https://examd.nowcoder.com/cts/preview/papers/17071483?p_token=L9mTCQXQaLsBUEfFzKlJMrKLgROj5Xk4",
    "testUrl" : "https://examd.nowcoder.com/cts/17071483/summary",
    "mobileTestUrl" : null,
    "assigned" : true,
    "testCount" : 0,
    "assignedCount" : 0,
    "paperSetting" : null,
    "presetUserCount" : 0,
    "paperExcelDownloadUrl" : null,
    "excelTaskStatus" : 0,
    "finished" : false,
    "started" : true,
    "setting" : {
      "logo" : "https://dev-private-public.oss-cn-hangzhou.aliyuncs.com/images/20201130/30_1606732062638/3669B06677BFB1053B71DAA1400C3083",
      "paperSummary" : "1. 请使用最新版Chrome浏览器作答(不低于82版),如考试需开启摄像头,请确保电脑带有摄像头。\n2. 一旦开始考试,请勿离开答题页面,除非当前目录明确提醒可以离开,前三次离开会有提醒,之后将不再提醒。各目录是否支持离开答题页面则取决于试卷具体设置,进入每个目录会有提示。\n3. 考试过程中允许使用草稿纸,请提前准备纸笔。允许上厕所等短暂离开,请控制离开时间。\n4. 考试期间如遇到断电、断网、死机等问题,关闭浏览器重新打开试卷链接即可继续做题。\n5. 遇到问题请即时反馈给考试主办方。",
      "examDisclaimer" : null,
      "antiJumpOut" : false,
      "antiDesignJumpOut" : true,
      "antiCodingJumpOut" : false,
      "codeSimilarRate" : 80,
      "setSourceCoderCheat" : false,
      "monitorPhone" : false,
      "allowMobileTest" : false,
      "noQueueUp" : false,
      "signUpFields" : [ {
        "title" : "姓名",
        "name" : "name",
        "format" : "",
        "need" : true,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "投递编号",
        "name" : "key",
        "format" : "",
        "need" : true,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "手机号码",
        "name" : "phone",
        "format" : "Phone",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "邮箱",
        "name" : "email",
        "format" : "Email",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "职位",
        "name" : "zhi2_wei4",
        "format" : "",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "学校",
        "name" : "xue2_xiao4",
        "format" : "",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "学历",
        "name" : "xue2_li4",
        "format" : "",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      } ],
      "relationType" : 0,
      "questionCategories" : {
        "100" : "1",
        "101" : "2",
        "102" : "3",
        "103" : "4"
      },
      "questionIdsTypes" : { },
      "questionScores" : null,
      "questionNewCounts" : null,
      "relationJsonString" : null,
      "questionCategoryRule" : null,
      "questionCategoryOrder" : null,
      "randomQuestion" : false,
      "customCategory" : true,
      "randomFrequentType" : 0,
      "version" : "1.0",
      "questionTagNames" : { },
      "codingScoreRule" : 1,
      "chooseScoreRule" : 3,
      "checkCheat" : true,
      "allowCopy" : false,
      "allowCalculator" : false,
      "contestDomain" : null,
      "navLogoUrl" : null,
      "hideNowcoder" : false,
      "simulation" : false,
      "languageLimit" : false,
      "languageList" : [ ],
      "reportPlatform" : true,
      "forbidPreview" : true,
      "needMobileCamera" : false,
      "codePlayback" : false,
      "timeLimitType" : 0,
      "timeLimitDetail" : null,
      "tiankongScores" : "{\"803922\":[20,21,22,23]}",
      "otherJobIds" : null,
      "subPaperSetting" : [ {
        "id" : 1,
        "name" : "子卷1",
        "intro" : "子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明",
        "categories" : "102,100,101"
      }, {
        "id" : 2,
        "name" : "子卷2",
        "intro" : "子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明",
        "categories" : "101,102,103"
      } ],
      "uploadFileTimeRange" : 0,
      "videoAnswerQuestionRule" : null,
      "lateNoticeSetting" : null,
      "paper_end_summary" : "本场考试已结束,请保持您的手机、邮箱畅通,方便接收后续通知。",
      "allow_new" : false,
      "allow_camera" : true,
      "allow_screen_record" : false,
      "allow_message" : false,
      "question_disorder" : true,
      "option_disorder" : true,
      "not_need_judge_type" : "3_4",
      "need_judge_type" : "5",
      "faq" : [ ],
      "hide_return_button" : true
    },
    "beenTested" : false,
    "passScoreLine" : null,
    "projectId" : 1643,
    "projectName" : "liumeng测试",
    "departmentList" : null,
    "previewOverdueTime" : null,
    "paperType" : null,
    "hasNotAttendTestUser" : false,
    "antiCheatStr" : "开启摄像头,题目乱序,选择题选项乱序,开启举报平台",
    "signUpFieldTitles" : "投递编号,姓名,手机号码,邮箱,职位,学校,学历",
    "creatorHrId" : 30,
    "creatorHrName" : null,
    "needJudge" : 0,
    "notStartedCount" : 0,
    "inProgressCount" : 0,
    "expiredCount" : 0,
    "cheatTaskStatus" : 0,
    "faceDetectedRation" : 0.0,
    "codeDetectedRation" : 0.0,
    "screenDetectedRation" : 0.0,
    "hasCodeQuestion" : false,
    "hasCtsPic" : true,
    "hasScreen" : false,
    "questionDesc" : "子卷1: 1 1 道,2 1 道,3 1 道<br>子卷2: 2 1 道,3 1 道,4 1 道<br>",
    "interviewPaper" : null,
    "forever" : true
  }, {
    "id" : 17071578,
    "paperName" : "magictest",
    "createTime" : 1615197295000,
    "duration" : 60,
    "score" : 36,
    "personTotal" : 3,
    "avgTotal" : 0.0,
    "summary" : "1、考前请关闭其他浏览器窗口,关闭QQ、微信等即时通信软件,关闭屏保、Outlook等弹窗提示软件,考试中不要切换到考试窗口之外的区域。<br/>\n2、请在规定时间内完成题目,答题过程中系统自动即时,到时自动交卷,请掌握好答题进度;<br/>\n3、请诚信答题,考试全程不要跳出考试页面(在线编程题除外),后台将记录你的跳出次数。编程题交卷后,我们将进行代码相似度判断,标示作弊嫌疑代码。<br/>\n4、笔试过程中遇到任务问题,请通过在线咨询小窗发消息给我们,我们会有相应人员解答。<br/>",
    "logo" : null,
    "questionCount" : 12,
    "diffcult" : 0,
    "beginTime" : 1615197295000,
    "endTime" : 1616818200000,
    "previewUrl" : "https://examd.nowcoder.com/cts/preview/papers/17071578?p_token=L9mTCQXQaLsBUEfFzKlJMrKLgROj5Xk4",
    "testUrl" : "https://examd.nowcoder.com/cts/17071578/summary",
    "mobileTestUrl" : null,
    "assigned" : false,
    "testCount" : 4,
    "assignedCount" : 0,
    "paperSetting" : null,
    "presetUserCount" : 7,
    "paperExcelDownloadUrl" : null,
    "excelTaskStatus" : 0,
    "finished" : true,
    "started" : true,
    "setting" : {
      "logo" : "https://dev-private-public.oss-cn-hangzhou.aliyuncs.com/images/20201130/30_1606732062638/3669B06677BFB1053B71DAA1400C3083",
      "paperSummary" : "1. 请使用最新版Chrome浏览器作答(不低于82版),如考试需开启摄像头,请确保电脑带有摄像头。\n2. 一旦开始考试,请勿离开答题页面,除非当前目录明确提醒可以离开,前三次离开会有提醒,之后将不再提醒。各目录是否支持离开答题页面则取决于试卷具体设置,进入每个目录会有提示。\n3. 考试过程中允许使用草稿纸,请提前准备纸笔。允许上厕所等短暂离开,请控制离开时间。\n4. 考试期间如遇到断电、断网、死机等问题,关闭浏览器重新打开试卷链接即可继续做题。\n5. 遇到问题请即时反馈给考试主办方。",
      "examDisclaimer" : null,
      "antiJumpOut" : false,
      "antiDesignJumpOut" : false,
      "antiCodingJumpOut" : false,
      "codeSimilarRate" : 80,
      "setSourceCoderCheat" : false,
      "monitorPhone" : false,
      "allowMobileTest" : false,
      "noQueueUp" : false,
      "signUpFields" : [ {
        "title" : "姓名",
        "name" : "name",
        "format" : "",
        "need" : true,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "投递编号",
        "name" : "key",
        "format" : "",
        "need" : true,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "手机号码",
        "name" : "phone",
        "format" : "Phone",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "邮箱",
        "name" : "email",
        "format" : "Email",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "职位",
        "name" : "zhi2_wei4",
        "format" : "",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "学校",
        "name" : "xue2_xiao4",
        "format" : "",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      }, {
        "title" : "学历",
        "name" : "xue2_li4",
        "format" : "",
        "need" : false,
        "edit" : 0,
        "valueType" : 0,
        "valueList" : null
      } ],
      "relationType" : 0,
      "questionCategories" : {
        "1" : "单选"
      },
      "questionIdsTypes" : { },
      "questionScores" : null,
      "questionNewCounts" : null,
      "relationJsonString" : null,
      "questionCategoryRule" : null,
      "questionCategoryOrder" : "1,2,3,4,5",
      "randomQuestion" : false,
      "customCategory" : false,
      "randomFrequentType" : 0,
      "version" : "1.0",
      "questionTagNames" : { },
      "codingScoreRule" : 1,
      "chooseScoreRule" : 3,
      "checkCheat" : true,
      "allowCopy" : false,
      "allowCalculator" : false,
      "contestDomain" : null,
      "navLogoUrl" : null,
      "hideNowcoder" : false,
      "simulation" : false,
      "languageLimit" : false,
      "languageList" : [ ],
      "reportPlatform" : true,
      "forbidPreview" : true,
      "needMobileCamera" : false,
      "codePlayback" : false,
      "timeLimitType" : 0,
      "timeLimitDetail" : null,
      "tiankongScores" : "{}",
      "otherJobIds" : null,
      "subPaperSetting" : null,
      "uploadFileTimeRange" : 0,
      "videoAnswerQuestionRule" : null,
      "lateNoticeSetting" : null,
      "paper_end_summary" : "本场考试已结束,请保持您的手机、邮箱畅通,方便接收后续通知。",
      "allow_new" : false,
      "allow_camera" : true,
      "allow_screen_record" : false,
      "allow_message" : false,
      "question_disorder" : true,
      "option_disorder" : true,
      "not_need_judge_type" : "3_4",
      "need_judge_type" : "5",
      "faq" : [ ],
      "hide_return_button" : true
    },
    "beenTested" : false,
    "passScoreLine" : null,
    "projectId" : 1643,
    "projectName" : "liumeng测试",
    "departmentList" : null,
    "previewOverdueTime" : null,
    "paperType" : null,
    "hasNotAttendTestUser" : false,
    "antiCheatStr" : "开启摄像头,题目乱序,选择题选项乱序,开启举报平台",
    "signUpFieldTitles" : "投递编号,姓名,手机号码,邮箱,职位,学校,学历",
    "creatorHrId" : 30,
    "creatorHrName" : null,
    "needJudge" : 0,
    "notStartedCount" : 0,
    "inProgressCount" : 0,
    "expiredCount" : 0,
    "cheatTaskStatus" : 3,
    "faceDetectedRation" : 0.0,
    "codeDetectedRation" : 0.0,
    "screenDetectedRation" : 0.0,
    "hasCodeQuestion" : false,
    "hasCtsPic" : true,
    "hasScreen" : false,
    "questionDesc" : "单选 12 道",
    "interviewPaper" : null,
    "forever" : false
  } ]
}

根据试卷id批量获取试卷。开发者可以通过考生所属的试卷id来获取试卷的详细信息。如果试卷id不存在,会返回code=1的报错。

接口地址

GET /papers/multi

请求参数

参数 类型 是否必传 默认值 描述
paperIds List<Long> 试卷id

返回数据

试卷信息数组,试卷关键信息见试卷关键返回字段

删除试卷

public class Main {
  @Test
  public void testDeletePaper() {
    long paperId = 17131854;
    String path = String.format("/papers/%d", paperId);

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "DELETE");

    System.out.println(responseString);
  }
}
curl --location --request DELETE 'https://dapi.nowcoder.com/v1/papers/17131854' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com'
{
  "code" : 0,
  "msg" : "OK",
  "data" : "OK"
}

根据试卷id删除试卷,删除之后,试卷的做题记录将同时清除。这个接口是幂等的,可以删除已经删除的试卷(无事发生)。

接口地址

DELETE /papers/{paperId}

请求参数

参数 类型 是否必传 默认值 描述
paperId int 需填充在url中 试卷id

返回数据

不需要关注返回数据。只需要检查接口请求是否成功(返回HTTP状态码为 200 且内容中的code=0

根据试卷ID获取试卷信息

public class Main {
  @Test
  public void testGetPaperPreview() {
    long paperId = 17071578;
    String path = String.format("/papers/%d", paperId);

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");

    System.out.println(responseString);
  }
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/papers/17071578/previews' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&shortUrl=true'
{
  "code" : 0,
  "msg" : "OK",
  "data" : "https://dwz.cn/HTQwVSEe"
}

接口地址

GET /papers/{paperId}

请求参数

参数 类型 是否必传 默认值 描述
paperId int 不能小于1,需填充在url中 试卷id

返回数据

试卷信息数组,试卷关键信息见试卷关键返回字段

分享试卷预览

public class Main { 
  @Test
  public void testGetPaperPreview() {
    long paperId = 17071578;
    String path = String.format("/papers/%d/previews", paperId);

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("shortUrl", true);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");

    System.out.println(responseString);
  }
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/papers/17071578/previews' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&shortUrl=true'
{
  "code" : 0,
  "msg" : "OK",
  "data" : "https://dwz.cn/U4QdDWK8"
}

接口可以用于在开发者自己的系统中预览牛客的试卷。

接口地址

POST /papers/{paperId}/previews

请求参数

参数 类型 是否必传 默认值 描述
paperId long 不能小于1,需填充在url中 试卷id
shortUrl boolean 默认true,可以为false 是否需要转换成短链接

返回数据

字符串类型的链接地址。

笔试-考生管理

(考生实体)关键字段

考生包含了考生的个人信息,每一位考生归属一张试卷,每一位考生有自己的专属笔试链接。

考生实体的创建、删除和查询可调用考生管理接口获取,下面是考生实体的一些关键字段。

参数 类型 描述
id long 考生id
testId String 考生id加密版,32位字符 (该字段建议入库保存,成绩报告回调时会回传testId字段,可用于进行考生成绩关联)
userKey String 业务侧唯一用户标识,同张试卷下userKey唯一(通过paperId+userKey,也可以用于成绩报告回调时关联)
name String 姓名
email String 邮箱
phone String 手机号
testUrl String 考生的专属考试链接
shortTestUrl String 考生的专属考试链接(短链形式,打开自动跳转testUrl,目前仅对AI面试场景开放)
testBeginTime Date 考试链接最早可以开始作答时间,如果试卷当前正在使用,该时间默认为考试链接生成时间;但如果试卷未开始,则该时间可能晚于当前时间
testExpireTime Date 考试链接过期时间(对长期有效链接,默认取值'9999-12-31';20240614之前创建的长期有效链接,该字段则为null)
started boolean 考生的考试是否已开始,true已开始
testStatus int 考生考试状态,1没有开始考试,2表示已经打开,3表示已经提交
note String 考生备注
paperId long 试卷id
paperName String 试卷名称
paperStarted boolean 试卷是否已开始
signStatus int 考生确认是否参加考试状态
noSignReason String 拒绝参加考试的原因
emailNotification int 邮件发起通知次数
smsNotification int 短信发起通知次数
emailSentStatus int 邮件发送状态, 0未发送,1发送中,2发送失败,3接收成功,4接收失败,5定时发送,6取消发送
smsSentStatus int 短信发送状态, 0未发送,1发送中,2发送失败,3接收成功,4接收失败,5定时发送,6取消发送
createTime Date 创建时间

(添加考生前)检测余额是否充足

public class Main {
  @Test
  public void testAddTestUsersCheckBalance() {
    String path = "/papers/test_users/checkBalance";

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    long paperId = 17071600;
    int userCnt = 2;
    mvMap.put("paperId_userCounts", paperId + "_" + userCnt);
    long anotherPaperId = 17071600;
    int anotherUserCnt = 2;
    mvMap.put("paperId_userCounts", anotherPaperId + "_" + anotherUserCnt);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/test_users/checkBalance?api_key=huaxinjiayou@126.com&paperId_userCounts=17071600_2&paperId_userCounts=17071600_2' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "hostId" : 30,
    "adminHrId" : 30,
    "moneyEnough" : true,
    "subAccountLimitEnough" : true
  }
}

在添加考生前,可以通过该接口预估添加考生时是否余额足够。

接口地址

GET /papers/test_users/checkBalance

请求参数

参数 类型 是否必传 默认值 描述
paperId_userCounts List<String> 格式为:试卷id_考生数量。可传多个 按试卷id聚合考生数量,

返回数据

参数 描述
hostId 当前账号id
adminHrId 当前账号的公司主账号id
moneyEnough 公司主账号的余额是否充足
subAccountLimitEnough 子账号分配的业务额度是否充足

添加考生

public class Main {
  @Test
  public void testAddTestUsers() {
    long paperId = 17131890;
    String path = String.format("/papers/%d/test_users", paperId);

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("name", "郭凯俊1");
    mvMap.put("key", "gkj1");
    mvMap.put("phone", "18812341234");
    mvMap.put("email", "guokaijun@nowcoder.com");
    mvMap.put("shen1_fen4_zheng4", "431123199911116666");
    mvMap.put("zhi2_wei4", "Java开发工程师");
    mvMap.put("xue2_xiao4", "清北大学");
    mvMap.put("xue2_li4", "本科");
    mvMap.put("note", "这个考生是通过API添加的");

    mvMap.put("name", "郭凯俊2");
    mvMap.put("key", "gkj2");
    mvMap.put("phone", "18812341234");
    mvMap.put("email", "guokaijun@nowcoder.com");
    mvMap.put("shen1_fen4_zheng4", "431123199911116666");
    mvMap.put("zhi2_wei4", "Java开发工程师");
    mvMap.put("xue2_xiao4", "清北大学");
    mvMap.put("xue2_li4", "本科");
    mvMap.put("note", "这个考生是通过API添加的");

    mvMap.put("failOnExist", false);
    mvMap.put("notice", false);
    mvMap.put("version", 0);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");

    System.out.println(responseString);
  }
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/papers/17131890/test_users' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&note=%E8%BF%99%E4%B8%AA%E8%80%83%E7%94%9F%E6%98%AF%E9%80%9A%E8%BF%87API%E6%B7%BB%E5%8A%A0%E7%9A%84&note=%E8%BF%99%E4%B8%AA%E8%80%83%E7%94%9F%E6%98%AF%E9%80%9A%E8%BF%87API%E6%B7%BB%E5%8A%A0%E7%9A%84&failOnExist=false&phone=18812341234&phone=18812341234&shen1_fen4_zheng4=431123199911116666&shen1_fen4_zheng4=431123199911116666&name=%E9%83%AD%E5%87%AF%E4%BF%8A1&name=%E9%83%AD%E5%87%AF%E4%BF%8A2&xue2_xiao4=%E6%B8%85%E5%8C%97%E5%A4%A7%E5%AD%A6&xue2_xiao4=%E6%B8%85%E5%8C%97%E5%A4%A7%E5%AD%A6&zhi2_wei4=Java%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88&zhi2_wei4=Java%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88&version=0&key=gkj1&key=gkj2&email=guokaijun%40nowcoder.com&email=guokaijun%40nowcoder.com&xue2_li4=%E6%9C%AC%E7%A7%91&xue2_li4=%E6%9C%AC%E7%A7%91&notice=false'
{
  "code" : 0,
  "msg" : "OK",
  "data" : [ {
    "id" : 2115087,
    "email" : null,
    "phone" : null,
    "testId" : "DCC8EDB8828E22D5",
    "paperId" : 17131890,
    "paperName" : null,
    "userKey" : "gkj1",
    "name" : null,
    "ext" : null,
    "testUrl" : "https://examd.nowcoder.com/cts/17131890/summary?id=DCC8EDB8828E22D5",
    "started" : false,
    "signStatus" : 0,
    "noSignReason" : null,
    "emailNotification" : 0,
    "smsNotification" : 0,
    "emailSentStatus" : 0,
    "smsSentStatus" : 0,
    "note" : null,
    "createTime" : null,
    "testStatus" : 0,
    "realTestId" : 0,
    "ctsDepartment" : null,
    "creatorHrUid" : 0,
    "creatorHrName" : null,
    "apiRole" : 0,
    "emailRecordCount" : 0,
    "smsRecordCount" : 0,
    "emailRecord" : null,
    "smsRecord" : null,
    "emailSuccessCount" : 0,
    "smsSuccessCount" : 0,
    "paperStarted" : false,
    "arrangeFeedbackId" : 0,
    "arrangeFeedbackTime" : null,
    "arrangeFeedbackContent" : null,
    "errMsg" : null,
    "paperStartTime" : 1735660800000,
    "paperEndTime" : 1738339200000
  }, {
    "id" : 2115088,
    "email" : null,
    "phone" : null,
    "testId" : "C72B030BD2287647",
    "paperId" : 17131890,
    "paperName" : null,
    "userKey" : "gkj2",
    "name" : null,
    "ext" : null,
    "testUrl" : "https://examd.nowcoder.com/cts/17131890/summary?id=C72B030BD2287647",
    "started" : false,
    "signStatus" : 0,
    "noSignReason" : null,
    "emailNotification" : 0,
    "smsNotification" : 0,
    "emailSentStatus" : 0,
    "smsSentStatus" : 0,
    "note" : null,
    "createTime" : null,
    "testStatus" : 0,
    "realTestId" : 0,
    "ctsDepartment" : null,
    "creatorHrUid" : 0,
    "creatorHrName" : null,
    "apiRole" : 0,
    "emailRecordCount" : 0,
    "smsRecordCount" : 0,
    "emailRecord" : null,
    "smsRecord" : null,
    "emailSuccessCount" : 0,
    "smsSuccessCount" : 0,
    "paperStarted" : false,
    "arrangeFeedbackId" : 0,
    "arrangeFeedbackTime" : null,
    "arrangeFeedbackContent" : null,
    "errMsg" : null,
    "paperStartTime" : 1735660800000,
    "paperEndTime" : 1738339200000
  } ]
}

接口用于向试卷中添加考生。如果试卷不允许用户自己报名参加,只有再这里添加的用户才能参加考试(直接打开接口返回的URL来考试)。 接口可以同时添加多个用户,即传多个keys和names参数,数量要保持一致。其他选填字段如手机、邮箱等,方式相同。 试卷配置中默认的手机字段为phone, 邮箱为email,其他为汉语拼音加声调加下划线。例如职位zhi2_wei4, 学历xue2_li4。

接口地址

POST /papers/{paperId}/test_users

请求参数

除列表中展示的字段外,还可以填入考生的其他选填字段。例如职位zhi2_wei4, 学历xue2_li4。详情见代码示例

参数 类型 是否必传 默认值 描述
paperId long 需填充在url中 试卷id
key List<String> 考试编号,在同一个试卷内唯一确定一个用户的字符串,不能包含emoji字符
name List<String> 和key对应的用户的姓名,姓名不能包含如下字符: `~!@#$%^&*()+=|{}':;[]<>/?!¥…()—【】‘;:”“’。、?
foreignKey List<String> 同1位候选人(自然人)在其它场景(比如AI面试)使用的考试编号,与key字段相对应。比如笔试场景下,key代表的是该候选人在本场考试下的考试编号,而foreignKey可代表该候选人在后续AI面试中的编号,通过这2个Key可以跨场景关联到同1个人。
userData List<String> 候选人信息,主要用于AI面试智能化出题、智能追问等场景,数据类型为json对象转string,json结构定义请参考文档候选人信息Json结构定义
callback String 回调地址,填写后将配置:完成考试、作弊检测、人工判题、考生被删除 四种类型的回调。更多关于回调类型的信息见:链接
failOnExist boolean 为true时,如果导入前这个考生的key已经存在,则直接返回失败
userType int 考生类型: 0 普通考生 1 测试考生,可提前进入考试答题。每张试卷可免费添加10个测试考生,超过部分将扣费
confirm boolean 当添加测试考生且即将扣费时,需要confirm=true时才能继续操作。
note List<String> 和key对应的用户的备注,可以不传
version int 0:当所有考生格式正确才会添加,1:格式正确考生会录入成功
notice boolean true:使用牛客默认模版发送手机短信和邮件通知,false:不发送
emailTemplateId int 仅在notice=true时有效,用于指定本次通知的邮件版本
smsTemplateId int 仅在notice=true时有效,用于指定本次通知的短信版本

返回数据

已经添加过的考生信息数组。接口需要关心下面的字段

参数 描述
errMsg 添加考生失败的时候,返回的考生id=0,此时这个字段会返回错误原因

其他参数见考生关键信息见考生关键返回字段

删除考生

public class Main {
  @Test
  public void testDeleteTestUser() {
    long paperId = 17131890;
    long testUserId = 2115115;
    String path = String.format("/papers/%d/test_users/%d", paperId, testUserId);
    // 考试已经开始无法删除考生。
    // 已经删除的考生无法删除。
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "DELETE");

    System.out.println(responseString);
  }
}
curl --location --request DELETE 'http://localhost:8888/v1/papers/17131890/test_users/2115115' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com'
# 删除成功
{
  "code" : 0,
  "msg" : "OK",
  "data" : "该考生未参加考试,考试费用15.0元已退回您的账户。"
}
# 考生曾经删除成功 或者 考生没有被添加过
{
  "code" : 1,
  "msg" : "考生不存在",
  "details" : null
}

通过考生id删除牛客系统中的一个考生。

接口地址

DELETE /papers/{paperId}/test_users/{id}

请求参数

参数 类型 是否必传 默认值 描述
paperId long 需填充在url中 试卷id
id long 需填充在url中 考生id

返回数据

无需关心返回数据,接口请求成功则视为删除成功

批量删除考生

public class Main {
  @Test
  public void testDeleteMultiTestUsers() {
    String delUsersPath = String.format("/papers/%d/test_users", 0);
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("ids", 2115077);
    mvMap.put("ids", 2115081);
    mvMap.put("paperIds", 17131890);
    mvMap.put("paperIds", 17131891);
    mvMap.put("isAll", 2);
    String responseString = NowcoderApiRequestUtils.request(delUsersPath, mvMap, "DELETE");

    System.out.println(responseString);
  }
}
curl --location --request DELETE 'https://dapi.nowcoder.com/v1/papers/0/test_users' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&ids=2115077&ids=2115081&isAll=2&paperIds=17131890&paperIds=17131891'
{
  "code" : 0,
  "msg" : "OK",
  "data" : "UBfCoqS08apsZ8QIEojbsmfpyxUCaYgh"
}

通过多个考生id批量删除牛客系统中的考生。该接口会异步进行处理。无需关心返回数据,接口请求成功则视为删除成功

接口地址

DELETE /papers/{paperId}/test_users

请求参数

参数 类型 是否必传 默认值 描述
ids List<Long> 考生id。可以填多个
paperIds List<Long> 试卷id,需要包含所有考生所属的试卷ids。可以填多个,但列表中id不能重复
isAll int 需传2 用于指定接口取paperIds
paperId long 需传0 用于填充参数中的url

返回数据

牛客异步任务id。

查询单个考生信息

public class Main {
  @Test
  public void testGetTestUser() {
    long paperId = 17131890;
    long testUserId = 2115086;
    String path = String.format("/papers/%d/test_users/%d", paperId, testUserId);
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/17131890/test_users/2115086?api_key=huaxinjiayou@126.com' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "id" : 2115086,
    "email" : "guokaijun@nowcoder.com",
    "phone" : "18812341234",
    "testId" : null,
    "paperId" : 17131890,
    "paperName" : null,
    "userKey" : "gkj",
    "name" : "郭凯俊",
    "ext" : "{\"phone\":\"18812341234\",\"name\":\"郭凯俊\",\"xue2_xiao4\":\"清北大学\",\"zhi2_wei4\":\"Java开发工程师\",\"key\":\"gkj\",\"email\":\"guokaijun@nowcoder.com\",\"xue2_li4\":\"本科\"}",
    "testUrl" : null,
    "started" : false,
    "signStatus" : 0,
    "noSignReason" : "",
    "emailNotification" : 0,
    "smsNotification" : 0,
    "emailSentStatus" : 0,
    "smsSentStatus" : 0,
    "note" : "这个考生是通过API添加的",
    "createTime" : 1628147456000,
    "testStatus" : 1,
    "realTestId" : 0,
    "ctsDepartment" : null,
    "creatorHrUid" : 30,
    "creatorHrName" : null,
    "apiRole" : 2,
    "emailRecordCount" : 0,
    "smsRecordCount" : 0,
    "emailRecord" : null,
    "smsRecord" : null,
    "emailSuccessCount" : 0,
    "smsSuccessCount" : 0,
    "paperStarted" : false,
    "arrangeFeedbackId" : 0,
    "arrangeFeedbackTime" : 1628147456000,
    "arrangeFeedbackContent" : null,
    "errMsg" : null,
    "paperStartTime" : null,
    "paperEndTime" : null
  }
}

接口用于查询单个考生的信息

接口地址

GET /papers/{paperId}/test_users/{id}

请求参数

参数 类型 是否必传 默认值 描述
paperId long 需填充在url中 试卷id
id long 需填充在url中 考生id

返回数据

考生关键信息见考生关键返回字段

更新单个考生信息

public class Main {
  @Test
  public void testUpdateTestUser() {
    long paperId = 17131890;
    long testUserId = 2115086;
    String path = String.format("/papers/%d/test_users/%d", paperId, testUserId);
    // 考试已经开始无法删除考生。
    // 已经删除的考生无法删除。
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("name", "郭凯俊");
    mvMap.put("key", "gkj");
    mvMap.put("phone", "18812341234");
    mvMap.put("email", "guokaijun@nowcoder.com");
    mvMap.put("shen1_fen4_zheng4", "431123199911116666");
    mvMap.put("zhi2_wei4", "Java开发工程师");
    mvMap.put("xue2_xiao4", "清北大学");
    mvMap.put("xue2_li4", "本科");
    mvMap.put("note", "这个考生是通过API添加的");
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "PUT");

    System.out.println(responseString);
  }
}
curl --location --request PUT 'https://dapi.nowcoder.com/v1/papers/17131890/test_users/2115086' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&note=%E8%BF%99%E4%B8%AA%E8%80%83%E7%94%9F%E6%98%AF%E9%80%9A%E8%BF%87API%E6%B7%BB%E5%8A%A0%E7%9A%84&phone=18812341234&shen1_fen4_zheng4=431123199911116666&name=%E9%83%AD%E5%87%AF%E4%BF%8A&xue2_xiao4=%E6%B8%85%E5%8C%97%E5%A4%A7%E5%AD%A6&zhi2_wei4=Java%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88&key=gkj&email=guokaijun%40nowcoder.com&xue2_li4=%E6%9C%AC%E7%A7%91'
{
  "code" : 0,
  "msg" : "OK",
  "data" : null
}

接口用于更新单个考生的信息

接口地址

PUT /papers/{paperId}/test_users/{id}

请求参数

参数 类型 是否必传 默认值 描述
paperId long 需填充在url中 试卷id
id long 需填充在url中 考生id
name String 考生姓名
key String 考试编号,在同一个试卷内唯一确定一个用户的字符串,不能包含emoji字符
departmentId long 所属部门,为0表示公开
userType int 考生类型
note String 备注
notice boolean 是否发送通知,true发送、false不发送
emailTemplateId int 默认模板 仅在notice=true时有效,用于指定本次通知的邮件版本
smsTemplateId int 默认模板 仅在notice=true时有效,用于指定本次通知的短信版本

返回数据

无需关心返回数据,接口请求成功则视为删除成功

批量查询当前考生状态

接口地址

/v1/partners/paper/batch_user_status

请求方法和类型

post, application/json

请求和回报参数见右边

请求参数:
{
  "paperId": "必填,long,试卷id",
  "userKeyList": "必填,string array,考试编号,单次最多查询50个考生"
}
回包参数:
{
  "code": "int:0表示成功,非0表示失败",
  "msg": "string:code非0时表示报错原因",
  "data": {
    "userList": [
      {
        "id": "long, 考生id",
        "userKey": "string, 考试编号",
        "status": "int, 考生状态,ai面试场景:1.面试未开始,2.待面试,3.已过期,4.面试中,5.已完成,6.判题完成;笔试场景:210.未进入考试,220.已开考,230.作答完成"
      }
    ]
  }
}

笔试-考生成绩管理

查询单个考生考试结果

public class Main {
  @Test
  public void testGetUserTestInfo() {
    String path = "/papers/usertestinfo";
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("paperId", 17131674);
    mvMap.put("userkey", "qwe");
    mvMap.put("needCategoryScore", true);
    mvMap.put("needCheatInfo", true);
    mvMap.put("needJudgeInfo", true);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/usertestinfo?api_key=huaxinjiayou@126.com&needCategoryScore=true&needCheatInfo=true&needJudgeInfo=true&paperId=17131674&userkey=qwe' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : [ {
    "paperName" : "编程题测试2",
    "pdfUrl" : "https://dapi.nowcoder.com/v1/test-pdf/F23269B6DFB0F586?paperId=17131674&tokenValue=cbe1f318a47b50c7e7f096ff6cbf2ed8746df596943e48f971a2a191a36ab07d&download=false",
    "userScore" : 0.0,
    "paperScore" : 60,
    "status" : 2,
    "cheatStatus" : 3,
    "beginTime" : 1626785242000,
    "finishTime" : 1626797842000,
    "createTime" : 1626785226000,
    "apiCategoryScores" : [ {
      "score" : 0.0,
      "categoryType" : 5,
      "questionType" : 5,
      "categoryName" : "问答"
    } ],
    "rankPercent" : 0.25,
    "cheatReasonList" : null,
    "judgeAssignAccountAndJudgeStatuses" : null,
    "judgeRemarkInfos" : null,
    "cheatInfoDesc" : null,
    "finalScore" : true
  } ]
}

查询单个考生考试结果信息。如果考生没有参加考试无法查到信息。

接口地址

GET /papers/usertestinfo

请求参数

参数 类型 是否必传 默认值 描述
paperId Long 试卷id(不传的话会查询所有试卷中考试编号为userkey的考生,传了就查指定试卷中的)
userkey String 考试编号,对应添加考生接口中key字段值
needCategoryScore boolean 是否需要不同题型得分
needCheatInfo boolean 是否需要作弊信息
needJudgeInfo boolean 是否需要人工判题信息,仅在paperId>0时有效
pdfFileType int 0 0表示返回在线预览的pdf地址,1表示返回可下载的pdf地址

返回数据

接口的返回数据由考生信息与考生测评信息结合而成。

参数 描述
paperName 试卷名称
pdfUrl 报告pdf链接
webReportUrl 在线报告链接
userScore 考生得分
paperScore 试卷满分
testResult 表示考试结果,取值passed表示“通过”,failed表示“不通过”
rejectionReasons 表示筛选不通过的原因(仅在testResult="failed"时有效);原因存在多项时,采用";"进行拼接;没值时用null表示
specialNotes 表示报告中需要特别关注的事情;存在多个关注事项时,采用";"进行拼接;没值时用null表示
moduleScores 表示考生按能力项维度聚合的得分情况。这个参数会有多个,每一个的参数格式是moduleScore|moduleName 如 "70.5|英语能力",moduleScore为skillScore的上级维度
skillScores 表示考生按技能项维度聚合的得分情况。这个参数会有多个,每一个的参数格式是skillScore|skillName 如 "60.5|抗压能力",skillScore为moduleScore的下级维度
status 考生未参加考试(-1),系统判题未完成(1), 考试进行中(0), 已交卷(2), 人工判题完成(4)
cheatStatus 作弊检测未完成(0), 作弊(1), 未作弊(2), 作弊疑似(3)
beginTime 开始答卷时间
finishTime 交卷时间
createTime 笔试的安排时间
elapseTime 测评消耗时间,单位是秒
rankPercent 浮点型排名百分比
rankScore 考生得分中位数
finalScore 是否是最终成绩:需要人工判题的,若人工判题完成则为最终成绩;无需人工判题的,只要交卷就是最终成绩
judgeRemarkInfos 判题备注,对象数组
cheatInfoDesc 作弊描述信息,单个字符串
apiCategoryScores 各个目录得分,对象数组
cheatReasonList 以文字表述的作弊原因字符串数组。具体信息见链接
judgeAssignAccountAndJudgeStatuses 判题备注 ,对象数组。分配的判题账户列表以及相应的完成状态
headUrl 考生自拍头像链接

目录得分数据结构

参数 描述
score 目录得分
categoryType 目录类型
questionType 题目类型:单选(1), 不定项选择(2), 填空(3), 编程(4), 问答(5) ,
categoryName 目录名称

目录得分数据结构

参数 描述
userId 判题的账号id
userName 判题的账号名称
judgeStatus 判题完成的状态,值枚举:已判题/未判题

判题备注数据结构

参数 描述
userName 判题的账号名称
summaryRemark 总体评价
questionRemarkInfos 各题目备注,对象数组
题目备注数据结构
字段 描述
questionName 例如:填空题第1题
remark 备注内容

获取某个用户拥有卷子的测评信息

public class Main {
  @Test
  public void testGetPaperTestsInfo() {
    String path = String.format("/tests/poid-%d", ConfigUtils.getNowcoderHrId());
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("projectIdList", 2227);
    mvMap.put("paperIds", 17131674);
    mvMap.put("page", 1);
    mvMap.put("pageSize", 1);
    mvMap.put("order", 2);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");

    System.out.println(responseString);
  }
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/tests/poid-30' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&pageSize=1&page=1&projectIdList=2227&paperIds=17131674&order=2'
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "totalCount" : 4,
    "totalPage" : 4,
    "currentPage" : 1,
    "datas" : [ {
      "id" : 1838108,
      "encryptId" : null,
      "actorId" : 2114808,
      "paperId" : 17131674,
      "paperName" : "编程题测试2",
      "finishTime" : 1626797842000,
      "status" : 2,
      "score" : 0.0,
      "paperScore" : 60.0,
      "paperOpenCount" : 4,
      "createTime" : 1626785242000,
      "actorType" : 10,
      "elapseTime" : 40,
      "leaveCount" : 4,
      "headUrl" : "",
      "signatureUrl" : null,
      "ipAddress" : "北京市",
      "ip" : "123.118.109.227",
      "cheated" : 3,
      "ncUser" : {
        "id" : 2114808,
        "email" : null,
        "nickname" : "aweqwe",
        "phone" : null,
        "displayName" : "aweqwe"
      },
      "user" : {
        "id" : 2114808,
        "email" : null,
        "nickname" : "aweqwe",
        "phone" : null,
        "displayName" : "aweqwe"
      },
      "testUserKey" : "qwe",
      "questionCount" : 0,
      "rightCount" : 0,
      "numberRank" : 1,
      "percentRank" : 0,
      "difficulty" : 0,
      "key" : null,
      "keyTitle" : null,
      "name" : null,
      "nameTitle" : null,
      "creatorHrUid" : 0,
      "creatorHrName" : "管理员",
      "pdfUrl" : null,
      "testResultUrl" : "https://dapi.nowcoder.com/v1/test-pdf/F23269B6DFB0F586?paperId=17131674&tokenValue=cbe1f318a47b50c7e7f096ff6cbf2ed8746df596943e48f971a2a191a36ab07d&download=false",
      "notJudgedTypes" : [ 3 ],
      "needJudge" : true,
      "picCount" : 0,
      "review" : null,
      "questionTypeList" : null,
      "categoryTypeList" : null,
      "signUpFields" : null,
      "userExt" : {
        "phone" : "",
        "name" : "aweqwe",
        "xue2_xiao4" : "",
        "zhi2_wei4" : "",
        "email" : "",
        "xue2_li4" : "",
        "key" : "qwe"
      },
      "remarkList" : null,
      "antiJumpOut" : false,
      "allowCamera" : false,
      "allowScreenRecord" : false,
      "monitorPhone" : false,
      "needMobileCamera" : false,
      "hasCodeProblem" : false,
      "hasHistoryData" : false,
      "judgingPermission" : null,
      "canSee" : true,
      "price" : 30.0,
      "cheatReasonList" : [ ],
      "testUserNote" : null,
      "paperSimulation" : false,
      "categoryScores" : null,
      "categoryTotalScores" : null,
      "timeCount" : null,
      "resumeId" : 0,
      "resumePermit" : 0,
      "recruitProjectId" : 0,
      "judged" : true,
      "notJudgedReason" : null,
      "judgingTip" : "需要人工阅卷的题目答案为空,系统自动判题",
      "resumeForJudge" : null,
      "deliverId" : 0,
      "testPeriod" : null,
      "clientSystem" : 1,
      "longValidTime" : true,
      "previewOverdueTime" : null,
      "tagNameList" : [ ],
      "bought" : true,
      "tagList" : null
    } ],
    "ext" : {
      "lackCount" : "0"
    }
  }
}

根据查询条件,查询当前账户下的考生成绩。

接口地址

POST /tests/poid-{paperOwnerId}

请求参数

参数 类型 是否必传 描述
paperOwnerId int 必传,需填充在url中 当前用户的HRId
paperIds List<Long> 非必传 用于筛选试卷id,可不传
projectIdList List<Long> 非必传 用于筛选项目id,可不传
page int 非必传,从1开始,默认为1 当前页数
pageSize int 非必传,默认为20 每页数量
orderBy int 非必传,默认0 根据什么排序,默认为0;0根据考生开始测评的时间排序,1根据考生完成测评的时间排序,2根据考生测评的分数排序
order int 非必传,默认1 升序还是降序,默认为1升序。1代表升序,2代表降序。

返回数据

参数 描述
totalCount 列表数据总数
totalPage 列表总页数
currentPage 当前是第几页,从1开始
datas 考生成绩数据数组

考生成绩对象数据结构

参数 描述
id 测评ID
encryptId 加密id
actorId 测评用户ID
paperId 测评点的试卷
paperName 试卷名字
finishTime 测评完成时间
status 测评状态
score 测评的分数
paperScore 试卷总分
paperOpenCount 试卷到场人数
createTime 测评开始时间
actorType 测评用户的类型
elapseTime 测评消耗时间,单位是秒
leaveCount 跳出次数
headUrl 头像
signatureUrl 签名url
ipAddress 考试地址
ip 考生考试ip地址
cheated 是否作弊:0-作弊检测任务未完成,1-作弊,2-未作弊,3-疑似作弊
testUserKey 考试测评用户的主key
questionCount 试题数量
rightCount 试题正确的数量
numberRank 名次
percentRank 百分比排名
key 唯一识别用户的Key
keyTitle key的标题
name 测评用户名字
nameTitle 测评用户名字的标题
creatorHrUid 创建测评用户的hr的uid
creatorHrName 创建测评用户的hr名字
pdfUrl 测评结果的PDF地址
testResultUrl 笔试报告地址,三方系统请使用此链接查看笔试报告
notJudgedTypes 不判题的题目类型
needJudge 试卷是否需要人工判题
picCount 截图的数量
review 牛客系统评语
questionTypeList 题型
signUpFields 需要录入的考生信息
judgingPermission 面试官查看权限
cheatReasonList 作弊原因,仅在cheated=1的时候有值,具体信息见链接
judged 是否已经判题
notJudgedReason 未判题的原因
clientSystem 答题设备1表示pc ,2表示ios 3表示android
tagNameList 判题所打的标签名字列表

笔试-回调服务

笔试回调服务以考生为维度进行回调,回调的信息为考生信息、考生的考试信息等信息。 回调地址为业务方在调用添加考生接口(POST /papers/{paperId}/test_user)中传入的callback参数。

回调类型、回调时机与回调配置

下面这些回调类型需要在调用创建考生接口时,添加callback参数配置回调地址即可订阅一个考生下列回调类型的回调。

回调类型 回调时机 回调说明
完成考试 考生手动交卷或考试时间截止自动交卷
作弊检测完成 牛客后台完成了对考生的作弊检测 如果存在作弊重判,可能触发多次回调
人工判题完成 牛客系统中有用户对考生进行了人工判题 仅对开启人工判题的试卷有效
考生被删除 在牛客系统或通过API删除了某个考生 只允许考前删除考生,不涉及成绩报告相关数据
附件上传结束 到了试卷设置附件上传截止时间或这期间的每天0点 仅对考后仍允许上传附件的试卷有效

下面这些回调类型需要联系牛客开发人员。进行配置

回调类型 回调时机 回调说明
考试结束 非长期有效试卷考试结束
成绩报告变化 考生成绩报告发生变化

如果无特殊要求,建议回调接收方按“可重入”的思路进行方案设计,默认以最新1次的回调结果为准。

回调参数

通用回调参数

完成考试作弊检测人工判题考试结束成绩报告变化这几种回调类型采用的时通用的回调参数。 考生删除链接过期等回调事件,不涉及成绩报告相关信息。

回调字段 类型 是否必填 描述
callbackType int 笔试场景下的回调类型:1.人工判题完成,3.完成考试,4.考试结束,5.成绩报告变化,6.作弊检测完成,8.考生被删除。 AI面试场景下的回调类型:201. 候选人被删除, 202. ai面试结束, 203. ai面试判题完成, 204. ai面试pdf报告生成完毕。使用建议:非特殊需要,不建议客户方对callbackType进行任何判断,牛客成绩报告默认均以最后1次回调为准,客户方客户保证回调操作可重入/覆盖式更新即可
testId String 测评id唯一标识(String类型),对应到添加考生接口返回的考生实体中的testId字段
numTestId long 测评id唯一标识(long类型),对应到添加考生接口返回的考生实体中的id字段
key String 业务侧用户唯一标识,对应到考生实体的userKey字段
status String 测评的状态 NOT_DO-未做题,DOING-正在做题,DONE-做完题,JUDGED-人工阅卷完成, CHEAT_DETECT_DONE-作弊检测完成,DELETE-删除
cheatStatus int 作弊检测状态 作弊检测未完成(0), 作弊(1), 未作弊(2), 作弊疑似(3)
cheatReasonList String 以文字表述的作弊原因字符串数组,具体格式为json中的string array转换出来的字符串。具体信息见链接,有值示例:["摄像头监控异常"],无值示例:[]
testStartTime long 考生开始考试时间(豪秒级)
testFinishTime long 考生交卷时间(豪秒级)
headUrl String 考生自拍头像链接
score float 考生试卷总得分(%.1f),笔试场景默认为必传,AI面试场景可能为null
scoreLeverType int 取值:0表示百分制形式;1表示5星形式;
scoreLever float 取值定义由scoreLeverType控制,当ScoreLeverType=0时,取值为score(%0.1f)字段值;当scoreLeverType=1时,取值为0.0,0.5,1.0,1.5,...,4.5,5.0,分别对应到5星档位;
testResult String 表示考试结果,取值passed表示“通过”,failed表示“不通过”
rejectionReasons String 表示筛选不通过的原因(仅在testResult="failed"时有效);原因存在多项时,采用";"进行拼接;没值时用null表示
specialNotes String 表示报告中需要特别关注的事情;存在多个关注事项时,采用";"进行拼接;没值时用null表示
isFinalScore boolean 是否是用户的最终成绩
moduleScores List[String] 表示考生按能力项维度聚合的得分情况。这个参数会有多个,每一个的参数格式是moduleScore|moduleName 如 "70.5|英语能力",moduleScore为skillScore的上级维度
moduleScoreLevers List[String] 表示考生按能力项维度聚合的得分等级情况。这个参数会有多个,每一个的参数格式是moduleScoreLever|moduleName 如 "3.5|英语能力",其中的moduleName与moduleScores中的moduleName一一对应
skillScores List[String] 表示考生按技能项维度聚合的得分情况。这个参数会有多个,每一个的参数格式是skillScore|skillName 如 "60.5|抗压能力",skillScore为moduleScore的下级维度
skillScoreLevers List[String] 表示考生按技能项维度聚合的得分等级情况。这个参数会有多个,每一个的参数格式是skillScoreLever|skillName 如 "4.0|抗压能力",其中的skillName与skillScores中的skillName一一对应
categoryScores List[String] 表示考生按试卷目录维度聚合的得分情况。这个参数会有多个,每一个的参数格式是score|categoryId|categoryName1.5|100|选择题。笔试场景默认为必传,AI面试场景为空
extDataItems List[String] 可扩展的信息维度。这个参数会有多个,每一个的参数格式是json string。结构:{"id": "xx", "name": "xxx", "value": "xxx"} 例子:{"name":"不通过原因","id":"rejectionReasons","value":"候选人放弃面试"}
rank int 考生排名,这个排名是在回调的时间点计算出来
isCheated boolean true、false 是否作弊,疑似作弊时为null(待废弃,以cheatStatus字段为准)
resultPdfUrl String 测评成绩报告的PDF版本的URL,支持按需配置
onlineTestResultUrl String 测评成绩报告的网页版本的URL,支持按需配置
paperName String 试卷名称
paperId long 试卷id
paperScore int 试卷满分,笔试和试卷中的题目总分有关,ai面试默认100分
needJudge boolean 试卷是否需要人工判题,true表示需要,false不表示不需要
isArchived boolean 代表当前考生是否可以归档,true表示可以归档,false表示还不能归档(该标识仅代表系统判定考生分数不再改变,但是可能存在手动修改考生成绩以及多次重新判题修改分数的情况)
public class Main {
  @Test
  public void escapeOnlineTestResultUrl() throws UnsupportedEncodingException {
    String onlineTestResultUrl = "https://dhr.nowcoder.com/console?theme=tinyLeft&access_token=1b60b47668a2459416985edfb4c4a2207cf318999c51715e00f722fd235b0b0b#paper/{\"tab\":\"index\",\"action\":\"candidate/result/index\",\"testId\":1837423}";
    int anchorIndex = onlineTestResultUrl.indexOf("#paper/");
    int encodeStrStartIndex = anchorIndex + "#paper/".length();
    String anchorStr  = StringUtils.substring(onlineTestResultUrl, encodeStrStartIndex);
    String encodedAnchorStr = URLEncoder.encode(anchorStr, "UTF-8");
    System.out.println(onlineTestResultUrl.substring(0, encodeStrStartIndex) + encodedAnchorStr);
  }
}

考生被删除

考试被删除时,只会回传考生的信息,具体参数如下:

回调字段 描述
hrId 用户id
status 测评的状态,在考生删除时为:DELETE(删除)
id 考生id
paperId 试卷id
paperName 试卷名称
key 唯一确定一个用户的字符串
note 考生备注

除了这些字段外,还会带上创建考生时填入的其他字段比如:phoneemail等字段。更多考生个人信息字段详见:添加考生接口

笔试-免登录判题

无需登录系统,开放给第三方的判题能力,该接口可获取判题链接,判题链接会失效过期,无需保存,需要时实时获取即可

接口地址

GET /judging-tests/quick-judge-url

请求参数

参数 类型 是否必传 默认值 描述
paperId Long 试卷id
userKey String 考试编号,对应添加考生接口中key字段值

返回数据

免登录判题短链
注意:链接有效期默认是2个月,从第一次请求接口生成时算起;同一个考生判题链接只会生成一次重复请求接口返回的是同一个判题链接

参数类型 描述

String 免登录判题短链

面试-项目管理

一个面试项目通常代表一次面试计划,候选人信息字段设置、现场管理功能都是以项目为单位。

面试项目实体的关键字段

字段名 类型 描述
id long id
name String 名称
remark String 备注
jobNums long 职位数目
studentNums long 面试数目
roundNums long 最大轮次数
status int 状态,0正常、1归档
type int 类型,0用户创建、1系统创建、2面试官自主预约
star int 是否置顶,0不置顶、1置顶

获取所有面试项目

public class Main {
  @Test
  public void testGetProjects() {
    String path = "/user/interview-projects/all";

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/user/interview-projects/all?api_key=huaxinjiayou@126.com' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : [ {
    "id" : 1638,
    "name" : "小程序测试",
    "remark" : "",
    "jobNums" : 2,
    "studentNums" : 32,
    "roundNums" : 5,
    "status" : 1,
    "type" : 0,
    "star" : 1,
  }, {
    "id" : 1746,
    "name" : "小程序",
    "remark" : "",
    "jobNums" : 10,
    "studentNums" : 88,
    "roundNums" : 4,
    "status" : 0,
    "type" : 0,
    "star" : 1,
  }, {
    "id" : 1291,
    "name" : "liumeng测试",
    "remark" : "liumeng 测试",
    "jobNums" : 30,
    "studentNums" : 357,
    "roundNums" : 14,
    "status" : 0,
    "type" : 0,
    "star" : 0,
  }, {
    "id" : 1293,
    "name" : "测试",
    "remark" : "呵呵呵",
    "jobNums" : 15,
    "studentNums" : 130,
    "roundNums" : 8,
    "status" : 0,
    "type" : 0,
    "star" : 0,
 }]
}

接口地址

GET /user/interview-projects/all

请求参数

返回数据

字段名 类型 描述
data array 面试项目数组,关键信息见面试项目关键返回字段

面试-面试管理

面试实体关键字段

字段名 类型 描述
id long id
interviewProjectId long 面试项目id
intervieweeName String 面试者(候选人)姓名
intervieweeEmail String 面试者(候选人)的邮箱
intervieweePhone String 面试者(候选人)的手机
jobType int 技术or非技术, 1技术面试、2非技术面试
job String 职位名称
deliverId String 投递编号
resumeUrl String 用户简历地址
testResultUrl String 笔试结果
round int 当前处于第几轮
rounds array 轮次实体关键字段
interviewReportUrl String 面试报告地址
startTime long 毫秒级时间戳、面试开始时间,即第一轮面试开始时间
expireTime long 毫秒级时间戳、过期时间,到达过期时间且面试未使用过会标记为过期并且退费
elapsedTime int 使用时长,单位毫秒
validTime int 总的可用时长,单位是秒, 如果为0则默认为3小时。使用时长超过可用时长后面试房间会无法使用,除非延长面试
interviewerUrl String 面试官面试地址
interviewerOfflineUrl String 面试官线下面试地址, 只有开启了线下面试权限才能使用
intervieweeUrl String 候选人面试地址
status int 状态,0表示正常,1表示删除,2表示过期。

轮次实体关键字段

字段名 类型 描述
id long id
interviewId long 面试id
round int 第几轮面试
bookTime long 预约时间、毫秒级时间戳
multi int 是否多对一面试,0一对一面试,1多对一面试
offline int 是否线下面试, 0线上,1线下
interviewerName String 一对一面试字段,面试官姓名
interviewerPhone String 一对一面试字段,面试官电话
interviewerEmail String 一对一面试字段,面试官邮箱
userList array 多对一面试字段,面试官实体关键字段
score int 面试评分,0未评分, 1-2未通过,3-5通过
evaluation String 评语
elapsedTime long 该轮使用时长,单位毫秒
intervieweeImage String 候选人面试过程中的一张照片
status int 轮次状态,0未开始、1进行中、3结束、4删除、5暂停、7面试淘汰被自动取消

面试官实体关键字段

字段名 类型 描述
id long id
interviewId long 面试id
roundId long 轮次id
round int 第几轮面试
name String 面试官姓名
phone String 面试官电话
email String 面试官邮箱
host int 是否主持人,0非主持人,1主持人
evaluation String 面试评价
elapsedTime long 面试官面试时长, 单位毫秒, 非实时更新
status int 状态, 0初始、1删除、2面试中、4结束

额度检查

优先检查服务对应可用次数,当可用次数不够时使用账户余额进行检查

public class Main {
  @Test
  public void testCheckBalance() {
    String path = "/interviews/checkBalance";

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("techCount", 10);
    mvMap.put("unTechCount", 10);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/interviews/checkBalance?api_key=huaxinjiayou@126.com&unTechCount=10&techCount=10' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "hostId" : 30,
    "adminHrId" : 30,
    "moneyEnough" : true,
    "subAccountLimitEnough" : true
  }
}

接口地址

GET /interviews/checkBalance

请求参数

参数 类型 是否必填 描述
techCount int 必填 技术类面试数量
unTechCount int 必填 非技术类面试数量
copilotFlag boolean 非必填 是否开启智能面试(同时对techCount和unTechCount生效),不传默认是false

返回数据

参数 类型 描述
hostId long 当前账号id
adminHrId long 当前账号的公司主账号id
moneyEnough boolean 公司主账号的余额是否充足
subAccountLimitEnough boolean 子账号分配的业务额度是否充足

创建面试

public class Main {
  @Test
  public void testCreateInterview(){
    String path = "/interviews";

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("projectId", 2071);
    mvMap.put("intervieweeName", "nowcoder");
    mvMap.put("intervieweeEmail", "ee@nowcoder.com");
    mvMap.put("intervieweePhone", "10000000000");
    mvMap.put("copilotFlag", false);
    mvMap.put("job", "java");
    mvMap.put("jobType", 1);
    mvMap.put("jobDesc", "职业介绍");
    mvMap.put("deliverId", "TD6879239819");
    mvMap.put("resumeUrl", "https://www.nowcoder.com");
    mvMap.put("resumeText", "简历文本内容");
    mvMap.put("testResultUrl", "https://www.nowcoder.com");
    mvMap.put("rounds", "2021-08-26 11:00:00|coder|10000000000|er@nowcoder.com|0|0");
    mvMap.put("rounds", "2021-08-26 11:30:00|-|-|-|0|1");
    mvMap.put("multiUsers", "2|0|coder1|er1@nowcoder.com|10000000001|1");
    mvMap.put("multiUsers", "2|0|coder2|er2@nowcoder.com|10000000002|0");
    mvMap.put("callback", null);
    mvMap.put("callback2", null);
    mvMap.put("finishRedirectUrl", "https://www.nowcoder.com");
    mvMap.put("finishRedirectUrls", "https://www.nowcoder.com");
    mvMap.put("finishRedirectUrls", "https://www.nowcoder.com");
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");

    System.out.println(responseString);
  }
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/interviews' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&intervieweeName=nowcoder&multiUsers=2%7C0%7Ccoder1%7Cer1%40nowcoder.com%7C10000000001%7C1&multiUsers=2%7C0%7Ccoder2%7Cer2%40nowcoder.com%7C10000000002%7C0&finishRedirectUrl=https%3A%2F%2Fwww.nowcoder.com&intervieweePhone=10000000000&deliverId=TD6879239819&intervieweeEmail=ee%40nowcoder.com&resumeUrl=https%3A%2F%2Fwww.nowcoder.com&testResultUrl=https%3A%2F%2Fwww.nowcoder.com&job=java&jobType=1&projectId=2071&rounds=2021-08-26+11%3A00%3A00%7Ccoder%7C10000000000%7Cer%40nowcoder.com%7C0%7C0&rounds=2021-08-26+11%3A30%3A00%7C-%7C-%7C-%7C0%7C1&finishRedirectUrls=https%3A%2F%2Fwww.nowcoder.com&finishRedirectUrls=https%3A%2F%2Fwww.nowcoder.com'
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "id" : 36724903,
    "interviewProjectId" : 2071,
    "intervieweeName" : "nowcoder",
    "intervieweeEmail" : "ee@nowcoder.com",
    "intervieweePhone" : "10000000000",
    "jobType" : 1,
    "job" : "java",
    "deliverId" : "TD6879239819",
    "resumeUrl" : "https://www.nowcoder.com",
    "testResultUrl" : "https://www.nowcoder.com",
    "round" : 0,
    "rounds" : [ {
      "id" : 289423,
      "interviewId" : 36724903,
      "round" : 1,
      "bookTime" : 1629946800000,
      "multi" : 0,
      "offline" : 0,
      "interviewerName" : "coder",
      "interviewerPhone" : "10000000000",
      "interviewerEmail" : "er@nowcoder.com",
      "userList" : null,
      "score" : 0,
      "evaluation" : null,
      "elapsedTime" : 0,
      "status" : 0,
    }, {
      "id" : 289424,
      "interviewId" : 36724903,
      "round" : 2,
      "bookTime" : 1629948600000,
      "multi" : 1,
      "offline" : 0,
      "interviewerName" : null,
      "interviewerPhone" : null,
      "interviewerEmail" : null,
      "userList" : [{
        "id" : 186503,
        "interviewId" : 36724903,
        "roundId" : 289424,
        "round" : 2,
        "name" : "coder1",
        "email" : "er1@nowcoder.com",
        "phone" : "10000000001",
        "host" : 1,
        "evaluation" : null,
        "elapsedTime" : 0,
        "status" : 0
      }, {
        "id" : 186504,
        "interviewId" : 36724903,
        "roundId" : 289424,
        "round" : 2,
        "name" : "coder2",
        "email" : "er2@nowcoder.com",
        "phone" : "10000000002",
        "host" : 0,
        "evaluation" : null,
        "elapsedTime" : 0,
        "status" : 0
      }],
      "score" : 0,
      "evaluation" : null,
      "elapsedTime" : 0,
      "status" : 0
    }],
    "interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/712E34F318A80DEC5D2B1AAD67C4DCC3/report_pdf?code=NstxvwnE",
    "startTime" : null,
    "expireTime" : 1635072309584,
    "elapsedTime" : 0,
    "validTime" : 0,
    "interviewerUrl" : "https://examd.nowcoder.com/interview/36724903/interviewer?code=NstxvwnE",
    "interviewerOfflineUrl" : "https://examd.nowcoder.com/interview/36724903/offline?code=NstxvwnE",
    "intervieweeUrl" : "https://examd.nowcoder.com/interview/36724903/interviewee?code=WNDyBdkI",
    "status" : 0
  }
}

接口地址

POST /interviews

请求参数

参数 类型 是否必填 描述
projectId long 非必填 所属项目id
intervieweeName String 非必填 面试者的姓名
intervieweeEmail String 非必填 面试者email
intervieweePhone String 非必填 面试者手机号码
copilotFlag boolean 非必填(默认false) 是否开启智能面试
job String 非必填 面试职位名称
jobType int 必填 职位类型1-技术,2-非技术
jobDesc String 非必填(长度上限4K) 职位介绍
deliverId String 非必填 投递编号
resumeUrl String 非必填 简历URL
resumeText String 非必填(长度上限12K) 简历文本内容
testResultUrl String 非必填 笔试结果URL
rounds array 必填 轮次信息字符串
multiUsers array 多对一面试必填(一对一面试非必填) 多对一面试字段,面试官信息字符串
callback String 非必填(想使用对应回调功能必填) 面试轮次评价回调, 录音完成回调
callback2 String 非必填(想使用对应回调功能必填) 面试状态回调
finishRedirectUrl String 非必填(想使用对应回调功能必填) 面试结束后跳转链接,一般用于三方对接填写面试评价使用, 搭配评分接口使用
finishRedirectUrls array 非必填(想使用对应回调功能必填) 面试结束后跳转链接,一般用于三方对接填写面试评价使用, 搭配评分接口使用,这里适用于每一轮都需要不同的跳转链接,大小必须和rounds参数一样

轮次参数字段

参数 类型 是否必填 描述
bookTime String/long 非必填 预约时间, yyyy-MM-dd HH:mm:ss 或者 毫秒级时间戳
interviewerName String 非必填 一对一面试字段,面试官姓名
interviewerPhone String 非必填 一对一面试字段,面试官号码
interviewerEmail String 非必填 一对一面试字段,面试官邮箱
offline int 必填 0线上、1线下
multi int 必填 0一对一面试、1多对一面试

使用时按照列表顺序以'|'为分割符拼接起来,为空的参数可以用'-'替代

面试官参数字段

参数 类型 是否必填 描述
round int 非必填 第几轮的面试官
role int 非必填 固定值0
name String 非必填 面试官姓名
email String 非必填 面试官邮箱
phone String 非必填 面试官号码
host int 必填 0非主持人、1主持人

使用时按照列表顺序以'|'为分割符拼接起来,为空的参数可以用'-'替代

返回数据

面试实体关键字段

修改面试

public class Main {
  @Test
  public void testUpdateInterview(){
    long interviewId = 36724903;
    String path = String.format("/interviews/%d/interview", interviewId);

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("intervieweeName", "javaCoder");
    mvMap.put("intervieweeEmail", "java@nowcoder.com");
    mvMap.put("intervieweePhone", "10000000000");
    mvMap.put("job", "java");
    mvMap.put("jobType", 1);
    mvMap.put("deliverId", "TD6879239819");
    mvMap.put("resumeUrl", "https://www.nowcoder.com");
    mvMap.put("testResultUrl", "https://www.nowcoder.com");
    mvMap.put("rounds", "289423|2021-08-26 11:00:00|coder|10000000000|er@nowcoder.com|0|0");
    mvMap.put("rounds", "289424|2021-08-26 11:30:00|-|-|-|0|1");
    mvMap.put("multiUsers", "186503|2|0|coder1|er1@nowcoder.com|10000000001|1");
    mvMap.put("multiUsers", "186504|2|0|coder2|er2@nowcoder.com|10000000002|0");
    mvMap.put("callback", null);
    mvMap.put("callback2", null);
    mvMap.put("finishRedirectUrl", "https://www.nowcoder.com");
    mvMap.put("finishRedirectUrls", "https://www.nowcoder.com");
    mvMap.put("finishRedirectUrls", "https://www.nowcoder.com");
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "PUT");

    System.out.println(responseString);
  }
}
curl --location --request PUT 'https://dapi.nowcoder.com/v1/interviews/36724903/interview' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&intervieweeName=javaCoder&multiUsers=186503%7C2%7C0%7Ccoder1%7Cer1%40nowcoder.com%7C10000000001%7C1&multiUsers=186504%7C2%7C0%7Ccoder2%7Cer2%40nowcoder.com%7C10000000002%7C0&finishRedirectUrl=https%3A%2F%2Fwww.nowcoder.com&intervieweePhone=10000000000&deliverId=TD6879239819&intervieweeEmail=java%40nowcoder.com&resumeUrl=https%3A%2F%2Fwww.nowcoder.com&testResultUrl=https%3A%2F%2Fwww.nowcoder.com&job=java&jobType=1&rounds=289423%7C2021-08-26+11%3A00%3A00%7Ccoder%7C10000000000%7Cer%40nowcoder.com%7C0%7C0&rounds=289424%7C2021-08-26+11%3A30%3A00%7C-%7C-%7C-%7C0%7C1&finishRedirectUrls=https%3A%2F%2Fwww.nowcoder.com&finishRedirectUrls=https%3A%2F%2Fwww.nowcoder.com'
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "id" : 36724903,
    "interviewProjectId" : 2071,
    "intervieweeName" : "javaCoder",
    "intervieweeEmail" : "java@nowcoder.com",
    "intervieweePhone" : "10000000000",
    "jobType" : 1,
    "job" : "java",
    "deliverId" : "TD6879239819",
    "resumeUrl" : "https://www.nowcoder.com",
    "testResultUrl" : "https://www.nowcoder.com",
    "round" : 0,
    "rounds" : [ {
      "id" : 289423,
      "interviewId" : 36724903,
      "round" : 1,
      "bookTime" : 1629946800000,
      "multi" : 0,
      "offline" : 0,
      "interviewerName" : "coder",
      "interviewerPhone" : "10000000000",
      "interviewerEmail" : "er@nowcoder.com",
      "userList" : null,
      "score" : 0,
      "evaluation" : null,
      "elapsedTime" : 0,
      "status" : 0
    }, {
      "id" : 289424,
      "interviewId" : 36724903,
      "round" : 2,
      "bookTime" : 1629948600000,
      "multi" : 1,
      "offline" : 0,
      "interviewerName" : null,
      "interviewerPhone" : null,
      "interviewerEmail" : null,
      "userList" : [{
        "id" : 186503,
        "interviewId" : 36724903,
        "roundId" : 289424,
        "round" : 2,
        "name" : "coder1",
        "email" : "er1@nowcoder.com",
        "phone" : "10000000001",
        "host" : 1,
        "evaluation" : null,
        "elapsedTime" : 0,
        "status" : 0
      }, {
        "id" : 186504,
        "interviewId" : 36724903,
        "roundId" : 289424,
        "round" : 2,
        "name" : "coder2",
        "email" : "er2@nowcoder.com",
        "phone" : "10000000002",
        "host" : 0,
        "evaluation" : null,
        "elapsedTime" : 0,
        "status" : 0
      }],
      "score" : 0,
      "evaluation" : null,
      "elapsedTime" : 0,
      "status" : 0
    }],
    "interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/712E34F318A80DEC5D2B1AAD67C4DCC3/report_pdf?code=NstxvwnE",
    "startTime" : null,
    "expireTime" : 1635072309584,
    "elapsedTime" : 0,
    "validTime" : 0,
    "interviewerUrl" : "https://examd.nowcoder.com/interview/36724903/interviewer?code=NstxvwnE",
    "interviewerOfflineUrl" : "https://examd.nowcoder.com/interview/36724903/offline?code=NstxvwnE",
    "intervieweeUrl" : "https://examd.nowcoder.com/interview/36724903/interviewee?code=WNDyBdkI",
    "status" : 0
  }
}

接口地址

PUT /interviews/{id:[0-9]+}/interview

请求参数

参数 类型 是否必填 描述
id long 必填 面试id
intervieweeName String 非必填 面试者的姓名
intervieweeEmail String 非必填 面试者email
intervieweePhone String 非必填 面试者手机号码
job String 非必填 面试职位名称
jobType int 必填 职位类型1-技术,2-非技术
deliverId String 非必填 投递编号
resumeUrl String 非必填 简历URL
testResultUrl String 非必填 笔试结果URL
rounds array 必填 轮次信息字符串
multiUsers array 多对一面试必填 多对一面试字段,面试官信息字符串
finishRedirectUrl String 非必填 面试结束后跳转链接,用于三方对接填写面试评价使用

轮次参数字段

参数 类型 是否必填 描述
id long 必填 轮次id
bookTime String/long 非必填 预约时间, yyyy-MM-dd HH:mm:ss 或者 毫秒级时间戳
interviewerName String 非必填 一对一面试字段,面试官姓名
interviewerPhone String 非必填 一对一面试字段,面试官号码
interviewerEmail String 非必填 一对一面试字段,面试官邮箱
offline int 必填 0线上、1线下
multi int 必填 0一对一面试、1多对一面试

使用时按照列表顺序以'|'为分割符拼接起来,为空的参数可以用'-'替代

面试官参数字段

参数 类型 是否必填 描述
id long 非必填 面试官id
round int 非必填 第几轮的面试官
role int 非必填 固定值0
name String 非必填 面试官姓名
email String 非必填 面试官邮箱
phone String 非必填 面试官号码
host int 必填 0非主持人、1主持人

使用时按照列表顺序以'|'为分割符拼接起来,为空的参数可以用'-'替代

返回数据

面试实体关键字段

取消一轮面试

public class Main {
  @Test
  public void testCancelInterviewRound(){
    long interviewId = 36724903;
    long roundId = 289424;
    String path = String.format("/interviews/%d/%d", interviewId, roundId);

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("cancelCurrentRoundOnly", true);
    mvMap.put("needSendCancelNotice", false);
    mvMap.put("cancelReason", "test");
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "DELETE");

    System.out.println(responseString);
  }
}
curl --location --request DELETE 'https://dapi.nowcoder.com/v1/interviews/36724903/289424' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&needSendCancelNotice=false&cancelCurrentRoundOnly=true&cancelReason=test'
{
  "code" : 0,
  "msg" : "OK",
  "data" : null
}

接口地址

DELETE /interviews/{id:[0-9]+}/{roundId:[0-9]+}

请求参数

参数 类型 是否必填 描述
id long 必填 面试Id
roundId long 必填 面试轮次id
cancelCurrentRoundOnly boolean 必填(默认为false) 是否只取消当前轮次而保留后面轮次
needSendCancelNotice boolean 必填(默认为false) 是否发送取消通知
cancelReason String 非必填 取消原因

返回数据

获取面试

public class Main {
  @Test
  public void testGetById() {
    long interviewId = 36724903;
    String path = String.format("/interviews/%d", interviewId);

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/interviews/36724903?api_key=huaxinjiayou@126.com' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
 {
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "id" : 36724903,
    "interviewProjectId" : 2071,
    "intervieweeName" : "javaCoder",
    "intervieweeEmail" : "java@nowcoder.com",
    "intervieweePhone" : "10000000000",
    "jobType" : 1,
    "job" : "java",
    "deliverId" : "TD6879239819",
    "resumeUrl" : "https://www.nowcoder.com",
    "testResultUrl" : "https://www.nowcoder.com",
    "round" : 0,
    "rounds" : [{
      "id" : 289423,
      "interviewId" : 36724903,
      "round" : 1,
      "bookTime" : 1629946800000,
      "multi" : 0,
      "offline" : 0,
      "interviewerName" : "coder",
      "interviewerPhone" : "10000000000",
      "interviewerEmail" : "er@nowcoder.com",
      "userList" : null,
      "score" : 0,
      "evaluation" : null,
      "elapsedTime" : 0,
      "status" : 0,
    }],
    "interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/712E34F318A80DEC5D2B1AAD67C4DCC3/report_pdf?code=NstxvwnE",
    "startTime" : null,
    "expireTime" : 1635072309584,
    "elapsedTime" : 0,
    "validTime" : 0,
    "interviewerUrl" : "https://examd.nowcoder.com/interview/36724903/interviewer?code=NstxvwnE",
    "interviewerOfflineUrl" : "https://examd.nowcoder.com/interview/36724903/offline?code=NstxvwnE",
    "intervieweeUrl" : "https://examd.nowcoder.com/interview/36724903/interviewee?code=WNDyBdkI",
    "status" : 0
  }
}

接口地址

GET /interviews/{id:[0-9]+}

请求参数

参数 类型 是否必填 描述
id long 必填 面试房间id

返回数据

面试实体关键字段

获取面试房间状态

public class Main {
  @Test
  public void testGetRoomStatus() {
    String path = "/interviews/room-status";

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("roomId", 36724903);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/interviews/room-status?api_key=huaxinjiayou@126.com&roomId=36724903' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "roomId" : 36724903,
    "timeRunOut" : false,
    "roomStatus" : 0,
    "remainMinitus" : 180
  }
}

接口地址

GET /interviews/room-status

请求参数

参数 类型 是否必填 描述
roomId long 必填 面试id

返回数据

参数 类型 描述
roomId long 面试id
timeRunOut boolean 面试是否已经超时
roomStatus int 房间状态:0-正常,1-取消,2-过期
remainMinitus int 剩余可用时长,单位:分钟. validTime - elapsedTime

批量获取面试官、候选人在线状态

public class Main {
  @Test
  public void testGetPersonStatus() {
    String path = "/interviews/rooms-status";

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("roomIdList", 36724903);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/interviews/rooms-status?api_key=huaxinjiayou@126.com&roomIdList=36724903' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : [ {
    "roomId" : 36724903,
    "intervieweeStatus" : 0,
    "interviewerStatus" : 0
  } ]
}

接口地址

GET /interviews/rooms-status

请求参数

参数 类型 是否必填 描述
roomIdList array 必填 面试id数组

返回数据

参数 类型 描述
roomId long 房间id
intervieweeStatus int 候选人在线状态:0-离线, 1-在线
interviewerStatus int 面试官在线状态:0-离线, 1-在线

延长面试

当面试的超时导致面试无法使用时,可以通过该接口延长可用时长,每次调用会延长一次初始时长,但会收取一次费用。

public class Main {
  @Test
  public void testExtendInterview() {
    long interviewId = 36724903;
    String path = String.format("/interviews/%d/extend", interviewId);

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "PUT");

    System.out.println(responseString);
  }
}
curl --location --request PUT 'https://dapi.nowcoder.com/v1/interviews/36724903/extend' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com'
{
  "code" : 0,
  "msg" : "OK",
  "data" : null
}

接口地址

PUT /interviews/{id:[0-9]+}/extend

请求参数

参数 类型 是否必填 描述
id long 必填 面试id

返回数据

轮次评分

public class Main {
  @Test
  public void testInterviewEvaluation() {
    String path = "/user/interviews-other/round/evaluations";

    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    mvMap.put("version", 1);
    mvMap.put("roundId", 289423);
    mvMap.put("interviewId", 36724903);
    mvMap.put("roundIdx", 1);
    mvMap.put("isPass", true);
    String responseString = NowcoderApiRequestUtils.request(path, mvMap, "PUT");

    System.out.println(responseString);
  }
}
curl --location --request PUT 'https://dapi.nowcoder.com/v1/user/interviews-other/round/evaluations' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  \
 --data-raw 'api_key=huaxinjiayou%40126.com&interviewId=36724903&roundIdx=1&isPass=true&version=1&roundId=289423'
{
  "code" : 0,
  "msg" : "OK",
  "data" : { }
}

接口地址

PUT /user/interviews-other/round/evaluations

请求参数

参数 类型 是否必填 描述
version int 必填 固定值 1
roundId long 必填 轮次id
interviewId long 必填 面试id
roundIdx int 必填 第几轮
isPass bool 必填 是否通过

返回数据

空json串

ai智能报告点赞点踩

接口地址

/v1/partners/interview/report/prefer

请求方法和类型

post, application/json

鉴权方式

  1. url后面添加api_key的query参数,如:/v1/partners/interview/report/prefer?api_key=xxx
  2. 请求添加一个Authorization头,值为:Bearer token,这个token可以从hr系统获得

请求和回报参数见右边

请求参数:
{
  "roundId": "面试轮次id,long",
  "sceneType": "场景类型,int:1.报告点赞,2.报告点踩,3.评价维度点赞,4.评价维度点踩,5.答题分析点赞,6.答题分析点踩",
  "sceneId": "场景id,string:sceneType=1,2时不传;sceneType=3,4时,代表dimensionId;sceneType=5,6时,代表analysisId"
}
回包参数:
{
    "code": "int:0表示成功,非0表示失败",
    "msg": "string:code非0时表示报错原因"
}

面试-新版面试管理

基础规范

  1. Content-Type统一使用application/json
  2. 如果参数的非空校验、格式校验等基础校验失败,Response Status会返回400。其他情况Response Status统一使用200,返回值中code为0代表成功,其他代表失败

面试实体字段

字段名称 类型 描述
interviewId long 面试id
expireTime long 秒级时间戳,过期失效时间
validDuration long 可用时长
interviewReportUrl String 面试报告地址
interviewRounds array 轮次信息

轮次实体字段

字段名称 类型 描述
roundId long 轮次id
roundIdx int 第几轮,从1开始计数
offline int 线上视频面试 或 线下面试, 0表示线上视频,1表示线下面试
interviewType int 技术面试 或 非技术面试, 1表示技术面试,2表示非技术面试
panelFlag int 1对1面试 或 多对1面试, 0表示1对1面试,1表示多对1面试
bookTime long 面试预约时间,秒级时间戳
interviewers array 面试官信息
interviewee json 候选人信息

面试官实体字段

字段名称 类型 描述
interviewerId long 多对一面试字段, 面试官id
name String 面试官姓名
email String 面试官邮箱
phone String 面试官电话
host int 是否主持人,0代表非主持人,1代表主持人
interviewUrl String 面试官链接,https格式

候选人实体字段

字段名称 类型 描述
name String 候选人姓名
email String 候选人邮箱
phone String 候选人电话
interviewUrl String 候选人链接,https格式,如果线下面试则不存在

创建面试-新版

public class Main {
  @Test
  public void testNewCreateInterview(){
    String path = "/partners/interview/create_interview";

    PartnerInterviewDTO partnerInterviewDTO = new PartnerInterviewDTO();
    PartnerInterviewDTO.OrgInfo orgInfo = new PartnerInterviewDTO.OrgInfo();
    orgInfo.projectId = 2071L;
    orgInfo.deptId = null;

    PartnerInterviewDTO.Interviewee interviewee = new PartnerInterviewDTO.Interviewee();
    interviewee.name = "coder";
    interviewee.email = "coder@nowcoder.com";
    interviewee.phone = "10000000000";
    interviewee.resumeUrl = "https://www.nowcoder.com";

    PartnerInterviewDTO.JobInfo jobInfo = new PartnerInterviewDTO.JobInfo();
    jobInfo.jobName = "java";
    jobInfo.deliverId = "TD12983710892";

    List<PartnerInterviewDTO.InterviewRound> interviewRounds = new ArrayList<>();
    PartnerInterviewDTO.InterviewRound interviewRound = new PartnerInterviewDTO.InterviewRound();
    interviewRound.offline = 0;
    interviewRound.interviewType = 1;
    interviewRound.panelFlag = 0;
    interviewRound.bookTime = 1629982394L;
    interviewRounds.add(interviewRound);

    List<PartnerInterviewDTO.Interviewer> interviewers = new ArrayList<>();
    PartnerInterviewDTO.Interviewer interviewer = new PartnerInterviewDTO.Interviewer();
    interviewer.name = "er";
    interviewer.email = "er@nowcoder.com";
    interviewer.phone = "10000000000";
    interviewer.host = 1;
    interviewers.add(interviewer);
    interviewRound.interviewers = interviewers;

    partnerInterviewDTO.interviewee = interviewee;
    partnerInterviewDTO.jobInfo = jobInfo;
    partnerInterviewDTO.interviewRounds = interviewRounds;
    partnerInterviewDTO.orgInfo = orgInfo;

    String response = NowcoderApiRequestUtils.jsonRequest(path, partnerInterviewDTO, "POST");
    System.out.println(response);
  }
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/partners/interview/create_interview?api_key=huaxinjiayou@126.com' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
 --header 'Content-Type: application/json'  \
 --data-raw '{"interviewRounds":[{"bookTime":1629982394,"interviewType":1,"interviewers":[{"email":"er@nowcoder.com","host":1,"name":"er","phone":"10000000000"}],"offline":0,"panelFlag":0}],"interviewee":{"email":"coder@nowcoder.com","name":"coder","phone":"10000000000","resumeUrl":"https://www.nowcoder.com"},"jobInfo":{"deliverId":"TD12983710892","jobName":"java"},"orgInfo":{"projectId":2071}}'
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "interviewId" : 37000637,
    "expireTime" : 1635080281,
    "validDuration" : 10800,
    "interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/844C0F4B8BD9E8685D2B1AAD67C4DCC3/report_pdf?code=QQGnFJCH",
    "interviewRounds" : [ {
      "roundId" : 289426,
      "roundIdx" : 1,
      "offline" : 0,
      "panelFlag" : 0,
      "bookTime" : 1629982394,
      "interviewer" : [ {
        "interviewerId" : null,
        "name" : "er",
        "email" : "er@nowcoder.com",
        "phone" : "10000000000",
        "host" : 1,
        "interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewer?code=QQGnFJCH"
      } ],
      "interviewee" : {
        "name" : "coder",
        "email" : "coder@nowcoder.com",
        "phone" : "10000000000",
        "interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewee?code=SSEb3BCn"
      },
      "interviewType" : 1
    } ]
  }
}

接口地址

POST /partners/interview/create_interview

Content-type

application/json

请求参数

参数 类型 是否必填 描述
orgInfo json 必填 系统信息
interviewee json 必填 候选人信息
jobInfo json 必填 岗位信息
interviewRounds array 必填 轮次信息
callback json 非必填 回调信息

系统信息

参数名称 类型 是否必填 描述
projectId long 必填 面试所属项目id
deptId long 非必填 面试所属部门id
copilotFlag boolean 非必填(默认false) 是否开启智能面试
resumeText String 非必填(长度上限12K) 简历文本内容

候选人信息

参数名称 类型 是否必填 描述
name String 非必填 候选人姓名
email String 非必填 候选人邮箱
phone String 非必填 候选人电话
resumeUrl String 非必填 候选人简历地址

岗位信息

参数名称 类型 是否必填 描述
deliverId String 非必填 投递编号, 同一个面试项目下唯一
jobName String 非必填 应聘岗位名称

轮次信息

参数名称 类型 是否必填 描述
offline int 必填 线上视频 或 线下面试, 0表示线上视频,1表示线下面试
interviewType int 必填 技术面试 或 非技术面试, 1表示技术面试,2表示非技术面试
panelFlag int 必填 1对1面试 或 多对1面试, 0表示1对1面试,1表示多对1面试
bookTime long 必填 面试预约时间, 秒级时间戳
redirectUrl json 非必填, 一对一面试用到 重定向链接
interviewers array 必填 面试官信息

面试官信息

参数名称 类型 是否必填 描述
name String 非必填 面试官姓名
email String 非必填 面试官邮箱
phone String 非必填 面试官电话
host int 必填 是否主持人 0代表非主持人, 1代表主持人
feedbackCb String 非必填, 多对一面试用到 自定义面评表地址, https格式。
redirectUrl json 非必填, 多对一面试用到 重定向链接

重定向链接

参数名称 类型 是否必填 描述
finishRedirectUrl String 非必填 结束时的重定向链接

回调链接

参数名称 类型 是否必填 描述
evaluationCallbackUrl String 非必填(想使用对应回调功能必填) 面试轮次评价回调, 录音完成回调

返回数据

面试信息

非全量修改面试-新版

public class Main {
  @Test
  public void testNewUpdateInterview(){
    String path = "/partners/interview/part-update-interview";

    PartnerInterviewDTO partnerInterviewDTO = new PartnerInterviewDTO();
    PartnerInterviewDTO.OrgInfo orgInfo = new PartnerInterviewDTO.OrgInfo();
    orgInfo.deptId = null;

    PartnerInterviewDTO.Interviewee interviewee = new PartnerInterviewDTO.Interviewee();
    interviewee.name = "coder5";

    partnerInterviewDTO.interviewId = 37000637L;
    partnerInterviewDTO.interviewee = interviewee;

    String response = NowcoderApiRequestUtils.jsonRequest(path, partnerInterviewDTO, "POST");
    System.out.println(response);
  }
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/partners/interview/part-update-interview?api_key=huaxinjiayou@126.com' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
 --header 'Content-Type: application/json'  \
 --data-raw '{"interviewId":37000637,"interviewee":{"name":"coder5"}}'
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "interviewId" : 37000637,
    "expireTime" : 1856005081,
    "validDuration" : 10800,
    "interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/844C0F4B8BD9E8685D2B1AAD67C4DCC3/report_pdf?code=QQGnFJCH",
    "interviewRounds" : [ {
      "roundId" : 289426,
      "roundIdx" : 1,
      "offline" : 0,
      "panelFlag" : 0,
      "bookTime" : 1629982394,
      "interviewer" : [ {
        "interviewerId" : null,
        "name" : "er",
        "email" : "er@nowcoder.com",
        "phone" : "10000000000",
        "host" : 1,
        "interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewer?code=QQGnFJCH"
      } ],
      "interviewee" : {
        "name" : "coder5",
        "email" : "coder2@nowcoder.com",
        "phone" : "10000000000",
        "interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewee?code=SSEb3BCn"
      },
      "interviewType" : 1
    }, {
      "roundId" : 289428,
      "roundIdx" : 2,
      "offline" : 0,
      "panelFlag" : 0,
      "bookTime" : 1656322593,
      "interviewer" : [ {
        "interviewerId" : null,
        "name" : null,
        "email" : null,
        "phone" : "14700000000",
        "host" : 1,
        "interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewer?code=QQGnFJCH"
      } ],
      "interviewee" : {
        "name" : "coder5",
        "email" : "coder2@nowcoder.com",
        "phone" : "10000000000",
        "interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewee?code=SSEb3BCn"
      },
      "interviewType" : 1
    } ]
  }
}

接口地址

POST /partners/interview/part-update-interview

Content-type

application/json

请求参数

参数 类型 是否必填 描述
interviewId long 必填 面试id
orgInfo json 非必填 系统信息
interviewee json 非必填 候选人信息
jobInfo json 非必填 岗位信息
interviewRounds array 非必填 轮次信息

系统信息

参数名称 类型 是否必填 描述
deptId long 非必填 面试所属部门id

候选人信息

参数名称 类型 是否必填 描述
name String 非必填 候选人姓名
email String 非必填 候选人邮箱
phone String 非必填 候选人电话
resumeUrl String 非必填 候选人简历地址

岗位信息

参数名称 类型 是否必填 描述
deliverId String 非必填 投递编号,同一个面试项目下唯一
jobName String 非必填 应聘岗位名称

轮次信息

参数名称 类型 是否必填 描述
roundId long 需要修改轮次时填写 需要修改的轮次id,新增时不填
offline int 非必填 线上视频 或 线下面试, 0表示线上视频,1表示线下面试, 必填
interviewType int 非必填 技术面试 或 非技术面试, 1表示技术面试,2表示非技术面试, 必填
panelFlag int 非必填 1对1面试 或 多对1面试, 0表示1对1面试,1表示多对1面试, 必填
bookTime long 非必填 面试预约时间, 秒级时间戳, 必填
redirectUrl json 非必填, 一对一面试用到 重定向链接
interviewers array 非必填 面试官信息

面试官信息

参数名称 类型 是否必填 描述
interviewerId long 多对一面试修改面试官填写 面试官id,多对一面试修改时传入
name String 非必填 面试官姓名, 必填
email String 非必填 面试官邮箱
phone String 非必填 面试官电话
host int 非必填 是否主持人 0代表非主持人, 1代表主持人 必填
delete boolean 非必填,默认false 是否删除面试官,多对一时用到
feedbackCb String 非必填,多对一面试用到 自定义面评表地址, https格式
redirectUrl json 非必填,多对一面试用到 重定向链接

重定向链接

参数名称 类型 是否必填 描述
finishRedirectUrl String 非必填 结束时的重定向链接

返回数据

面试信息

修改面试-新版(建议使用非全量修改接口)

public class Main {
  @Test
  public void testNewUpdateInterview(){
    String path = "/partners/interview/update_interview";

    PartnerInterviewDTO partnerInterviewDTO = new PartnerInterviewDTO();
    PartnerInterviewDTO.OrgInfo orgInfo = new PartnerInterviewDTO.OrgInfo();
    orgInfo.deptId = null;

    PartnerInterviewDTO.Interviewee interviewee = new PartnerInterviewDTO.Interviewee();
    interviewee.name = "coder2";
    interviewee.email = "coder2@nowcoder.com";
    interviewee.phone = "10000000000";
    interviewee.resumeUrl = "https://www.nowcoder.com";

    PartnerInterviewDTO.JobInfo jobInfo = new PartnerInterviewDTO.JobInfo();
    jobInfo.jobName = "java";
    jobInfo.deliverId = "TD12983710892";

    List<PartnerInterviewDTO.InterviewRound> interviewRounds = new ArrayList<>();
    PartnerInterviewDTO.InterviewRound interviewRound = new PartnerInterviewDTO.InterviewRound();
    interviewRound.roundId = 289426L;
    interviewRound.offline = 0;
    interviewRound.interviewType = 1;
    interviewRound.panelFlag = 0;
    interviewRound.bookTime = 1629982394L;
    interviewRounds.add(interviewRound);

    List<PartnerInterviewDTO.Interviewer> interviewers = new ArrayList<>();
    PartnerInterviewDTO.Interviewer interviewer = new PartnerInterviewDTO.Interviewer();
    interviewer.name = "er";
    interviewer.email = "er@nowcoder.com";
    interviewer.phone = "10000000000";
    interviewer.host = 1;
    interviewers.add(interviewer);
    interviewRound.interviewers = interviewers;

    partnerInterviewDTO.interviewId = 37000637L;
    partnerInterviewDTO.interviewee = interviewee;
    partnerInterviewDTO.jobInfo = jobInfo;
    partnerInterviewDTO.interviewRounds = interviewRounds;
    partnerInterviewDTO.orgInfo = orgInfo;

    String response = NowcoderApiRequestUtils.jsonRequest(path, partnerInterviewDTO, "POST");
    System.out.println(response);
  }
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/partners/interview/update_interview?api_key=huaxinjiayou@126.com' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
 --header 'Content-Type: application/json'  \
 --data-raw '{"interviewId":37000637,"interviewRounds":[{"bookTime":1629982394,"interviewType":1,"interviewers":[{"email":"er@nowcoder.com","host":1,"name":"er","phone":"10000000000"}],"offline":0,"panelFlag":0,"roundId":289426}],"interviewee":{"email":"coder2@nowcoder.com","name":"coder2","phone":"10000000000","resumeUrl":"https://www.nowcoder.com"},"jobInfo":{"deliverId":"TD12983710892","jobName":"java"},"orgInfo":{}}'
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "interviewId" : 37000637,
    "expireTime" : 1635080281,
    "validDuration" : 10800,
    "interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/844C0F4B8BD9E8685D2B1AAD67C4DCC3/report_pdf?code=QQGnFJCH",
    "interviewRounds" : [ {
      "roundId" : 289426,
      "roundIdx" : 1,
      "offline" : 0,
      "panelFlag" : 0,
      "bookTime" : 1629982394,
      "interviewer" : [ {
        "interviewerId" : null,
        "name" : "er",
        "email" : "er@nowcoder.com",
        "phone" : "10000000000",
        "host" : 1,
        "interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewer?code=QQGnFJCH"
      } ],
      "interviewee" : {
        "name" : "coder2",
        "email" : "coder2@nowcoder.com",
        "phone" : "10000000000",
        "interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewee?code=SSEb3BCn"
      },
      "interviewType" : 1
    } ]
  }
}

接口地址

POST /partners/interview/update_interview

Content-type

application/json

请求参数

参数 类型 是否必填 描述
interviewId long 必填 面试id
orgInfo json 必填 系统信息
interviewee json 必填 候选人信息
jobInfo json 必填 岗位信息
interviewRounds array 必填 轮次信息

系统信息

参数名称 类型 是否必填 描述
deptId long 必填 面试所属部门id

候选人信息

参数名称 类型 是否必填 描述
name String 非必填 候选人姓名
email String 非必填 候选人邮箱
phone String 非必填 候选人电话
resumeUrl String 非必填 候选人简历地址

岗位信息

参数名称 类型 是否必填 描述
deliverId String 必填 投递编号,同一个面试项目下唯一
jobName String 非必填 应聘岗位名称

轮次信息

参数名称 类型 是否必填 描述
roundId long 修改轮次信息时必填,增加轮次时不填 需要修改的轮次id
offline int 必填 线上视频 或 线下面试, 0表示线上视频,1表示线下面试, 必填
interviewType int 必填 技术面试 或 非技术面试, 1表示技术面试,2表示非技术面试, 必填
panelFlag int 必填 1对1面试 或 多对1面试, 0表示1对1面试,1表示多对1面试, 必填
bookTime long 必填 面试预约时间, 秒级时间戳, 必填
redirectUrl json 非必填, 一对一面试用到 重定向链接
interviewers array 必填 面试官信息

面试官信息

参数名称 类型 是否必填 描述
interviewerId long 多对一面试修改必填 面试官id,多对一面试修改时传入
name String 非必填 面试官姓名, 必填
email String 非必填 面试官邮箱
phone String 非必填 面试官电话
host int 必填 是否主持人 0代表非主持人, 1代表主持人 必填
feedbackCb String 非必填, 多对一面试用到 自定义面评表地址, https格式
redirectUrl json 非必填,多对一面试用到 重定向链接

重定向链接

参数名称 类型 是否必填 描述
finishRedirectUrl String 非必填 结束时的重定向链接

返回数据

面试信息

面试录音下载

public class Main {
  @Test
  public void testGetJobProcess() {
    String interviewId = "31310396";

    String path = String.format("/partners/interview/get-record-url/%s", interviewId);
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = CommonUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/partners/interview/get-record-url?interviewId=31310396&api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c1273a4e338f650a5c'
{
    "code": 0,
    "msg": "OK",
    "data": {
        "interviewId": 31310396,
        "roundRecordDatas": [
            {
                "roundId": 430801,
                "round": 1,
                "roundStatus": 3,
                "recordUrl": null,
                "recordExpireTime": null
            },
            {
                "roundId": 430802,
                "round": 2,
                "roundStatus": 3,
                "recordUrl": null,
                "recordExpireTime": null
            }
        ]
    }
}

接口地址

GET /partners/interview/get-record-url

Content-type

application/json

请求参数

参数 类型 是否必填 描述
interviewId long 必填 面试房间id

返回数据

字段名 类型 描述
interviewId long 面试房间id
roundRecordDatas array 录音数组,关键信息见录音信息实体

录音实体字段

字段名称 类型 描述
rounId long 轮次id
round int 当前轮次
roundStatus int 轮次状态,0未开始、1进行中、3结束、4删除、5暂停、7面试淘汰被自动取消
recordUrl String 录音下载链接 (不存在返回null)
recordExpireTime long 下载链接过期时间(注意是秒级时间戳,不存在返回null)

面试-回调服务

面试轮次评价回调

回调时机

  1. 每一轮面试结束时进行回调
  2. 轮次评分修改分数后进行回调

回调参数

参数名称 类型 描述
interviewId long 面试id
roundId long 面试轮次id
round int 第几轮
score int 0未评分、1-2淘汰、3-5通过
evaluation String 评语
reportUrl Stirng 报告链接
deliverId String 投递编号
interviewerName String 面试官姓名,以最后评价填写的为准
roundStatus int 固定值3,代表面试结束
roundStartTime long 该轮面试开始时间
roundEndTime long 该轮面试结束时间
roundElapsedTime String 该轮使用时长,单位毫秒
autoCancelRounds array 自动取消轮次信息,如果开启了淘汰取消后续轮次这里会携带被自动取消的轮次信息
interviewerEvaluations array 多对一面试非主持人评价信息

自动取消轮次信息

参数名称 类型 描述
id long 轮次id
round int 第几轮, 被折叠的轮次也会记录

多对一面试非主持人评价信息

参数名称 类型 描述
interviewerName String 面试官姓名
interviewerEvaluations String 面试官评价

面试状态回调

回调时机

  1. 面试开始使用
  2. 面试删除、过期
  3. 候选人或面试官上线

回调参数

参数名称 类型 描述
interviewId long 面试id
status int 状态, 1取消、2过期、3开始使用、4面试官或候选人上线
参数名称 类型 描述
round int 第几轮
roundId long 轮次id
role int 0面试官、1候选人
onlineTime long 毫秒级时间戳, 上线时间
bookTime long 毫秒级时间戳,预约时间
uid long 多对一面试时面试官id

录音文件生成回调

回调时机

  1. 生成面试录音文件

回调参数

参数名称 类型 描述
interviewId long 面试id
roundId long 面试轮次id
round int 第几轮
score int 0未评分、1-2淘汰、3-5通过
evaluation String 评语
deliverId String 投递编号
interviewerName String 面试官姓名,以最后评价填写的为准
recordUrl String 面试录音下载链接
roundStatus int 固定值3,代表面试结束
roundStartTime long 该轮面试开始时间
roundEndTime long 该轮面试结束时间
roundElapsedTime String 该轮使用时长,单位毫秒
autoCancelRounds array 自动取消轮次信息,如果开启了淘汰取消后续轮次这里会携带被自动取消的轮次信息

ai智能报告回调

回调说明

收到该回调表示面试轮次ai智能报告已经生成,相关答题分析和面试记录可以通过下面两个接口来拉取

请求方法和类型

post, application/x-www-form-urlencoded

回调参数

参数名称 类型 描述
uid string 账号id
time long 时间戳
sec string 加密后的内容
data string 回调的数据,是个json字符串,结构见右边
回调参数中data对应的json结构:
{
    "interviewId": "面试id,long",
    "roundId": "面试轮次id,long",
    "round": "表示第几轮,int",
}
回包参数:
{
  "code": "int:200表示成功,非200表示失败",
  "message": "string:表示失败时的报错原因"
}

答题分析获取接口

接口地址

/v1/partners/interview/report/answer-analysis

请求方法和类型

get

鉴权方式

  1. url后面添加api_key的query参数,如:/v1/partners/interview/answer-analysis?api_key=xxx
  2. 请求添加一个Authorization头,值为:"Bearer token",其中的token可以从hr系统获得

请求query参数

参数名称 类型 描述
roundId long 必填,轮次id

回包参数见右边

{
  "code": "int:0表示成功,非0表示失败",
  "msg": "string:code非0时表示报错原因",
  "data": {
    "assessmentDimensionList": [
      {
        "name": "维度名称,string:学习能力",
        "assessment": "维度评价内容,string:候选人应对挫折和卡点,容易陷入自我怀疑与否定...",
        "dimensionId": "维度评价id,string:249483jsfjoe"
      }
    ],
    "answerAnalysisList": [
      {
        "chatList": [
          {
            "roleType": "角色类型,int: 0.面试官,1.候选人",
            "roleName": "角色名称,string:面试官",
            "content": "对话的内容,string:请你做个自我介绍"
          }
        ],
        "skills": [
          "考察技能名称,string:Java"
        ],
        "advice": "答题分析建议,string:候选人回答基本正确,但掌握比较基础,建议深入考核",
        "analysisId": "答题分析建议id,string:2898598543jfosdjfoi"
      }
    ]
  }
}

面试记录获取接口

接口地址

/v1/partners/interview/report/chat-list

请求方法和类型

get

鉴权方式

  1. url后面添加api_key的query参数,如:/v1/partners/interview/chat-list?api_key=xxx
  2. 请求添加一个Authorization头,值为:"Bearer token",其中的token可以从hr系统获得

请求query参数

参数名称 类型 描述
roundId long 必填,轮次id
curPage int 选填,请求页,默认值1
pageSize int 选填,每页大小,默认值20

回包参数见右边

{
  "code": "int:0表示成功,非0表示失败",
  "msg": "string:code非0时表示报错原因",
  "data": {
    "totalCount": "int: 总条数",
    "totalPage": "int:总页数",
    "curPage": "int:当前页",
    "pageSize": "int:当前每页大小",
    "originChatList": [
      {
        "roleType": "角色类型,int: 0.面试官,1.候选人",
        "roleName": "角色名称,string:比如面试官",
        "content": "对话的内容,string:请你做个自我介绍",
        "actionTime": "对话时间戳,long:毫秒时间戳"
      }
    ]
  }
}

系统接口

获取用户当前账户信息

public class Main {
    @Test
    public void testGetUserTestInfo() {
        String path = "/users/self";
        MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
        String responseString = CommonUtils.request(path, mvMap, "GET");

        System.out.println(responseString);
    }
}
curl --location --request GET 'http://localhost:8888/v1/users/self?api_key=huaxinjiayou@126.com' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "id" : 30,
    "email" : "huaxinjiayou@126.com",
    "phone" : null,
    "companyName" : "华鑫加油",
    "headUrl" : null,
    "accountConfig" : null,
    "validBeginTime" : null,
    "validEndTime" : null,
    "encryptPassword" : null
  }
}

查询当前用户的账户信息

接口地址

GET /users/self

请求参数

返回数据

参数 描述
id 账号id
email 账号登录邮箱
phone 账号手机
companyName 公司名称,不同于账号名称
headUrl 头像
validBeginTime 有效期开始时间
validEndTime 有效期开始时间
encryptPassword 加密密码

获取hr系统每种服务的最大可用额度

public class Main {
    @Test
    public void testGetPaperTestsInfo() {
        String path = "/user/checkBalance/count";
        MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
        mvMap.put("serviceTypes", 1);
        mvMap.put("serviceTypes", 3);
        mvMap.put("serviceTypes", 7);
        mvMap.put("serviceTypes", 8);
        mvMap.put("serviceTypes", 9);
        String responseString = CommonUtils.request(path, mvMap, "GET");

        System.out.println(responseString);
    }
}
curl --location --request GET 'http://localhost:8888/v1/user/checkBalance/count?api_key=huaxinjiayou@126.com&serviceTypes=1&serviceTypes=3&serviceTypes=7&serviceTypes=8&serviceTypes=9' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "hostId" : 30,
    "adminHrId" : 30,
    "techContestCount" : 2176,
    "untechContestCount" : 4352,
    "techInterviewCount" : 932,
    "untechInterviewCount" : 1865,
    "extendPackageCount" : 3264
  }
}

查询每个服务类型最大可以使用的额度(包括额度和账户余额),包括技术笔试、非技术笔试、技术面试、非技术面试、面试扩展包。

最大可以使用额度计算方式:
技术笔试额度=合同剩余技术笔试额度+取整(账户余额/30)
非技术笔试额度=合同剩余非技术笔试额度+取整(账户余额/15)
技术面试额度=合同剩余技术面试额度+取整(账户余额/70)
非技术面试额度=合同剩余非技术笔试额度+取整(账户余额/35)
面试扩展包=合同剩余扩展包额度+取整(账户余额/20)

注:子账号查询,返回总账号/子账号的额度限制,取最小值

支持指定类型查询最大额度,例如 只查询笔试的;也可以支持不指定类型,查询全部最大额度;

接口地址

GET /user/checkBalance/count

请求参数

参数 描述|
serviceTypes 需要查询的服务类型,可以传多个值。1:技术面试,3:技术笔试,7:非技术面试,8:非技术笔试,9:面试扩展包

返回数据

参数 描述
hostId 当前用户ID
adminHrId 用户主账号ID,如果当前用户为主账号与用户ID相同
techContestCount 技术笔试可用额度,-1为无限制
untechContestCount 非技术笔试可用额度,-1为无限制
techInterviewCount 技术面试可用额度,-1为无限制
untechInterviewCount 非技术面试可用额度,-1为无限制
extendPackageCount 面试扩展包可用额度,-1为无限制,子账户此项默认返回父账可用最大额度

获取异步任务进度

public class Main {
  @Test
  public void testGetJobProcess() {
    String processId = "LntWBG4tD1YRyJ4z7woVSqaU5sxulx36";

    String path = String.format("/job-progress/%s", processId);
    MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
    String responseString = CommonUtils.request(path, mvMap, "GET");

    System.out.println(responseString);
  }
}
curl --location --request GET 'http://localhost:8888/v1/job-progress/LntWBG4tD1YRyJ4z7woVSqaU5sxulx36?api_key=huaxinjiayou@126.com' \
 --header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'  
{
  "code" : 0,
  "msg" : "OK",
  "data" : {
    "ownerId" : 0,
    "content" : "",
    "end" : true,
    "error" : false,
    "type" : 2,
    "progress" : 100,
    "jobId" : "LntWBG4tD1YRyJ4z7woVSqaU5sxulx36",
    "jobInfo" : null
  }
}

获取异步任务进度

接口地址

GET /job-progress/{id}

请求参数

参数 描述
id 异步任务id

返回数据

参数 描述
ownerId 账号id
jobId 异步任务id
progress 异步任务进度,0~100之间的整数
end 异步任务是否结束。true结束、false未结束
error 异步任务是否发生异常。true发生了异常、false未发生异常
content 异步任务返回信息
type content字段的类型,1-下载链接 2-文字结果 3-JSON字符串