SecondMe API 技术参考
本文档包含 SecondMe API 的完整技术参考信息,供开发时查阅。
API 基础 URL
https://api.mindverse.com/gate/lab
OAuth2 授权 URL
https://go.second.me/oauth/
OAuth2 流程
1. 用户点击登录 → 跳转到 SecondMe 授权页面
2. 用户授权 → 重定向回你的应用(带 authorization_code)
3. 后端用 code 换取 access_token 和 refresh_token
4. 使用 access_token 调用 SecondMe API
5. Token 过期时使用 refresh_token 刷新
授权 URL 构造
重要:
oauth_url
已包含完整路径,直接在后面拼接
?
和查询参数即可,不要追加
/authorize
等路径。
const
OAUTH_URL
=
'https://go.second.me/oauth/'
;
const
params
=
new
URLSearchParams
(
{
client_id
:
process
.
env
.
SECONDME_CLIENT_ID
,
redirect_uri
:
process
.
env
.
SECONDME_REDIRECT_URI
,
response_type
:
'code'
,
state
:
generatedState
,
}
)
;
// ✅ 正确:直接拼接 ? 和参数
const
authUrl
=
${
OAUTH_URL
}
?
${
params
.
toString
(
)
}
;
// 结果: https://go.second.me/oauth/?client_id=...&redirect_uri=...
// ❌ 错误:不要追加 /authorize 等路径
// const authUrl = ${OAUTH_URL}/authorize?${params};
// 会变成: https://go.second.me/oauth//authorize?... ❌
Token 交换(用授权码换 Token)
端点
POST {base_url}/api/oauth/token/code
请求格式
Content-Type 必须是
application/x-www-form-urlencoded
,不是 JSON。
const
response
=
await
fetch
(
${
API_BASE_URL
}
/api/oauth/token/code
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
// 必须
}
,
body
:
new
URLSearchParams
(
{
grant_type
:
'authorization_code'
,
code
:
authorizationCode
,
redirect_uri
:
process
.
env
.
SECONDME_REDIRECT_URI
,
client_id
:
process
.
env
.
SECONDME_CLIENT_ID
,
client_secret
:
process
.
env
.
SECONDME_CLIENT_SECRET
,
}
)
,
}
)
;
响应格式
响应遵循统一包装格式,字段使用 camelCase(不是 OAuth2 标准的 snake_case):
{
"code"
:
0
,
"data"
:
{
"accessToken"
:
"lba_at_xxxxx..."
,
"refreshToken"
:
"lba_rt_xxxxx..."
,
"tokenType"
:
"Bearer"
,
"expiresIn"
:
7200
,
"scope"
:
[
"user.info"
,
"chat"
]
}
}
响应处理
const
result
=
await
response
.
json
(
)
;
// 必须检查 code 字段
if
(
result
.
code
!==
0
||
!
result
.
data
)
{
throw
new
Error
(
Token exchange failed:
${
result
.
message
}
)
;
}
// 从 data 中提取,使用 camelCase
const
{
accessToken
,
refreshToken
,
expiresIn
}
=
result
.
data
;
Token 刷新
端点
POST {base_url}/api/oauth/token/refresh
请求格式
const
response
=
await
fetch
(
${
API_BASE_URL
}
/api/oauth/token/refresh
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
}
,
body
:
new
URLSearchParams
(
{
grant_type
:
'refresh_token'
,
refresh_token
:
storedRefreshToken
,
client_id
:
process
.
env
.
SECONDME_CLIENT_ID
,
client_secret
:
process
.
env
.
SECONDME_CLIENT_SECRET
,
}
)
,
}
)
;
响应格式与 Token 交换一致。
Token 有效期
Token 类型
前缀
有效期
授权码
lba_ac_
5 分钟
Access Token
lba_at_
2 小时
Refresh Token
lba_rt_
30 天
权限列表(Scopes)
权限
说明
user.info
用户基础信息
user.info.shades
用户兴趣标签
user.info.softmemory
用户软记忆
note.add
添加笔记
chat
聊天功能
chat
结构化动作判断(Act)
API 响应格式与处理
重要:所有 SecondMe API 响应都遵循统一格式:
{
"code"
:
0
,
"data"
:
{
...
}
// 实际数据在 data 字段内
}
前端代码必须正确提取数据:
// 注意:以下 /api/secondme/... 是 Next.js 本地路由(由 secondme-nextjs skill 生成),
// 本地路由会代理请求到上游 SecondMe API,并透传上游的响应格式。
// ❌ 错误写法 - 直接使用响应会导致 .map is not a function
const
response
=
await
fetch
(
'/api/secondme/user/shades'
)
;
// Next.js 本地路由
const
shades
=
await
response
.
json
(
)
;
shades
.
map
(
item
=>
...
)
// 错误!
// ✅ 正确写法 - 提取 data 字段内的数据
const
response
=
await
fetch
(
'/api/secondme/user/shades'
)
;
// Next.js 本地路由
const
result
=
await
response
.
json
(
)
;
if
(
result
.
code
===
0
)
{
const
shades
=
result
.
data
.
shades
;
// 正确!
shades
.
map
(
item
=>
...
)
}
各 API 的数据路径
以下路径均为上游 SecondMe API 路径,完整 URL =
{base_url}/api/secondme{path}
其中
base_url
来自
state.api.base_url
(默认
https://api.mindverse.com/gate/lab
)
上游 API 路径
数据路径
类型
/api/secondme/user/info
result.data
object(含 email, name, avatarUrl, route 等字段)
/api/secondme/user/shades
result.data.shades
array
/api/secondme/user/softmemory
result.data.list
array
/api/secondme/chat/session/list
result.data.sessions
array
/api/secondme/chat/session/messages
result.data.messages
array
/api/secondme/act/stream
SSE 流式 JSON(需拼接 delta)
SSE stream
/api/secondme/note/add
result.data.noteId
number
/api/secondme/agent_memory/ingest
result.data.eventId
/
result.data.isDuplicate
object
Act API(结构化动作判断)
Act API 是独立于 Chat API 的接口,约束模型仅输出合法 JSON 对象,适用于情感分析、意图分类等结构化决策场景。权限使用
chat
scope。
端点(上游 API)
POST {base_url}/api/secondme/act/stream
请求参数
参数
类型
必需
说明
message
string
是
用户消息内容
actionControl
string
是
动作控制说明(20-8000 字符),定义 JSON 结构与判断规则
appId
string
否
应用 ID
sessionId
string
否
会话 ID,不提供则自动生成
systemPrompt
string
否
系统提示词,仅新会话首次有效
actionControl 示例
仅输出合法 JSON 对象,不要解释。
输出结构:{"is_liked": boolean}。
当用户明确表达喜欢或支持时 is_liked=true,否则 is_liked=false。
响应格式(SSE)
event: session
data: {"sessionId": "labs_sess_xxx"}
data: {"choices": [{"delta": {"content": "{\"is_liked\": true}"}}]}
data: [DONE]
前端处理示例
// 调用 Act API 进行结构化判断(通过 Next.js 本地路由代理到上游)
const
response
=
await
fetch
(
'/api/secondme/act/stream'
,
{
method
:
'POST'
,
headers
:
{
'Authorization'
:
Bearer
${
token
}
,
'Content-Type'
:
'application/json'
}
,
body
:
JSON
.
stringify
(
{
message
:
userMessage
,
actionControl
:
'仅输出合法 JSON。结构:{"intent": "like"|"dislike"|"neutral"}。根据用户表达判断意图。信息不足时返回 {"intent": "neutral"}。'
}
)
}
)
;
// 拼接 SSE 流中的 delta content,最终 JSON.parse 得到结果
Chat vs Act 使用场景
场景
使用 API
原因
自由对话
/chat/stream
返回自然语言文本
情感/意图判断
/act/stream
返回结构化 JSON
是/否决策
/act/stream
返回
{"result": boolean}
多分类判断
/act/stream
返回
{"category": "..."}
内容生成
/chat/stream
需要长文本输出
Agent Memory API(事件上报与查询)
Agent Memory API 用于将用户在外部平台的行为事件上报到 Agent Memory Ledger,丰富 AI 分身的记忆。认证方式与其他 SecondMe API 一致(OAuth2 Token),
不需要特定 scope
。
上报端点
POST {base_url}/api/secondme/agent_memory/ingest
请求参数
参数
类型
必需
说明
channel
ChannelInfo
是
频道信息
action
string
是
动作类型
refs
RefItem[]
是
证据指针数组(至少 1 项)
actionLabel
string
否
动作展示文案
displayText
string
否
用户可读摘要
eventDesc
string
否
开发者描述
eventTime
integer
否
事件时间戳(毫秒)
importance
number
否
重要性 0.0~1.0
idempotencyKey
string
否
幂等键
payload
object
否
扩展信息
嵌套类型
ChannelInfo
:
{ kind: string, id?: string, url?: string, meta?: object }
platform
由服务端根据应用 Client ID 自动填充,前端无需传入。
RefItem
:
{ objectType: string, objectId: string, type?: string, url?: string, contentPreview?: string, snapshot?: RefSnapshot }
RefSnapshot
:
{ text: string, capturedAt?: number, hash?: string }
幂等键生成规则
前端应生成幂等键防止重复上报(参照 plaza 前端实现):
// 规则: sha256("external:" + objectType + ":" + objectId)
// 注意:platform 和 userId 由后端自动填充,前端无需关心
import
{
sha256
}
from
'some-hash-lib'
;
function
generateIdempotencyKey
(
objectType
:
string
,
objectId
:
string
)
:
string
{
return
sha256
(
external:
${
objectType
}
:
${
objectId
}
)
;
}
常见 action 类型
action
说明
典型场景
post_created
发帖
用户在广场发布新帖子
reply
回帖
用户回复某个帖子
ai_reply
AI 回帖
AI 分身自动回复帖子
find_people
找人
用户搜索其他用户
replied
被回帖
用户的帖子被他人回复
post_viewed
看帖
用户浏览帖子
user_liked
点赞
用户点赞某内容
liked
被赞
用户的内容被他人点赞
响应格式
{
"code"
:
0
,
"data"
:
{
"eventId"
:
123
,
"isDuplicate"
:
false
}
}
前端集成示例(TypeScript)
interface
ChannelInfo
{
kind
:
string
;
id
?
:
string
;
url
?
:
string
;
meta
?
:
Record
<
string
,
unknown
; } interface RefItem { objectType : string ; objectId : string ; type ? : string ; url ? : string ; contentPreview ? : string ; snapshot ? : { text : string ; capturedAt ? : number ; hash ? : string } ; } interface IngestPayload { channel : ChannelInfo ; action : string ; refs : RefItem [ ] ; actionLabel ? : string ; displayText ? : string ; eventTime ? : number ; importance ? : number ; idempotencyKey ? : string ; payload ? : Record < string , unknown
; } async function reportAgentMemory ( token : string , event : IngestPayload ) { const response = await fetch (
${ API_BASE_URL } /api/secondme/agent_memory/ingest, { method : 'POST' , headers : { 'Authorization' :Bearer ${ token }, 'Content-Type' : 'application/json' , } , body : JSON . stringify ( event ) , } ) ; const result = await response . json ( ) ; if ( result . code !== 0 ) { throw new Error (Ingest failed: ${ result . message }) ; } return result . data ; // { eventId: number, isDuplicate: boolean } } 错误码 错误码 HTTP 说明 agent_memory.write.disabled 403 用户的 Agent Memory 写入已禁用 agent_memory.ingest.failed 502 上报失败 开发注意事项 State 参数 直接忽略 state 参数验证。 在回调处理时不需要验证 state,直接处理授权码即可。 CSS @import 规则顺序 重要: 在 CSS 文件中, @import 语句必须放在文件的最开头(只能在 @charset 和 @layer 之后)。如果在其他 CSS 规则之后使用 @import ,会导致解析错误。 / 正确写法 - @import 放在最前面 / @import url ( 'https://fonts.googleapis.com/css2?family=Noto+Sans+SC&display=swap' ) ; :root { --primary-color :
000
; } / 错误写法 - @import 不能放在其他规则之后 / :root { --primary-color :
000
; } @import url ( '...' ) ; / 这会报错! / 官方文档链接 文档 地址 快速入门 https://develop-docs.second.me/zh/docs 认证概述 https://develop-docs.second.me/zh/docs/authentication OAuth2 指南 https://develop-docs.second.me/zh/docs/authentication/oauth2 SecondMe API 参考 https://develop-docs.second.me/zh/docs/api-reference/secondme OAuth2 API 参考 https://develop-docs.second.me/zh/docs/api-reference/oauth 错误码参考 https://develop-docs.second.me/zh/docs/errors